bind(Foo.class).to(Bar.class) 与 bind(Foo.class).toInstance(new Bar()) 之间的区别

Difference between bind(Foo.class).to(Bar.class) vs bind(Foo.class).toInstance(new Bar())

bind(Foo.class).to(Bar.class)bind(Foo.class).toInstance(new Bar())有什么区别;

此外,使用后一种调用构造函数的方法是否可以正确注入字段new Bar()

bind(Foo.class).to(Bar.class) 是一个 linked binding: you're telling Guice "whenever someone asks for a Foo, give them a Bar instead". You're not telling Guice how to create a Bar; this implies that there's an @Inject-annotated or public zero arg constructor and that you're allowing Guice to do everything it normally does including field injection. You're also not telling Guice whether to memoize the Bar instance and keep it around, meaning it will create a new Bar every time. (Note that this doesn't preclude you from bind(Bar.class).to(Baz.class) or bind(Bar.class).toInstance(new Baz()) if you wanted to; without one of those you're technically letting Bar be an implicit or JIT binding.)

bind(Foo.class).toInstance(new Bar())instance binding. You're telling Guice "whenever someone asks for a Foo, give them this Bar instead". Guice doesn't ever try to create a Bar, so it doesn't try to inject constructor parameters, and it also doesn't ever try to create a different Bar: you always get the same one. UPDATE: Thanks Tavian, I'd forgotten that automatic injections 允许在 toInstance 绑定上进行字段注入。 请注意,none 这会影响 Bar 的注入请求,仅影响 Foo。

因此,前者允许注入并每次都创建一个新实例,而后者允许您手动创建实例并且每次return都是同一个实例。这些也可以是两个单独的决定:

  • 要始终 return 相同的实例,您可以将 class 标记为 @Singleton,或者使您的绑定 .in(Singleton.class)。有关详细信息和选项,请参阅 Scopes。 Guice 创建实例,因此您可以访问字段注入。
  • 让您无需字段注入即可手动创建实例(但允许调用静态工厂方法或自定义初始化方法),bind to a Provider or create a @Provides method。 Guice 不会注入字段,因为你自己创造了。

    那些 provider/@Provides 绑定也可以成为单例,这类似于上面的 toInstance,但不需要您在创建注入器时创建您的实例。