在Guice中,以下命令有什么区别:
// Inside your AbstractModule subclass:
@Override
public void configure() {
bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
}和:
@Override
public void configure() {
bind(Service.class).to(ServiceImpl.class);
}
@Provides @Singleton
public ServiceImpl providesService() {
return new ServiceImpl();
}它们都是一样的吗?什么时候你会使用一种而不是另一种呢?提前谢谢。
发布于 2013-02-09 10:36:55
它们在上几乎完全相同。@Singleton语法对于批注@Provides方法或批注类本身很有用(尽管我更喜欢将范围批注保留在模块中)。
区别在于哪个键被标记为单例,这与@Singleton与Singleton.class (或Scopes.SINGLETON、asEagerSingleton、@Singleton类注释或toInstance隐式单例)的关系较小,而更多地与默认语法的简单性有关。例如:
public class MyModule extends AbstractModule {
@Override public void configure() {
bind(A.class).to(AImpl.class).in(Singleton.class);
bind(B.class).to(BImpl.class);
bind(BImpl.class).in(Singleton.class);
}
@Provides @Singleton C provideC() { return new CImpl(); }
@Provides @Singleton D provideD(DImpl dImpl) { return dImpl; }
@Provides E provideE(EImpl eImpl) { return eImpl; }
@Provides @Singleton EImpl provideEImpl() { return new EImpl(); }
}上面我们将接口A绑定到类AImpl,并将接口B绑定到类BImpl,但行为是不同的:
time.
A将检索相同的AImpl实例每个time.
AImpl每次都将检索不同的AImpl,所有这些都不同于A的B BImpl将检索相同的BImpl实例每个time.
BImpl还将检索B注入的相同<BImpl>D31实例。正如您所看到的,每个键都是不同的,如果仅将接口与Singleton绑定,则Guice将允许多个实现实例。如果您只注入A和B接口,行为看起来是相同的,但是如果您同时注入来自同一个Injector的接口和实现,您可能会看到不同的行为。
类似的逻辑也适用于@Provides方法:
C将始终返回相同的代码CImpl CImpl每次都会创建一个新的代码,除非代码没有可注入的公共零参数构造函数-那么注入将始终返回相同的代码instance.DImpl >D53DImpl>每次都将返回一个新的实例,并且每个实例都与D.E将返回相同的EImpl实例每个EImpl也将检索E注入的相同实例。这提供了一些灵活性。设想一个假设的Cache,它保存一定数量的最近检索的对象,其中您希望@User Cache和@Product Cache都是可注入的。如果你使用bind(Cache.class).in(Singleton.class),你将在对象(以及任何空的Cache注入)之间共享一个缓存,而如果你使用bind(Cache.class).annotatedWith(User.class).to(Cache.class).in(Singleton.class),那么带注释的键将被保存在单例作用域中,并且每种对象类型都将拥有自己的缓存。
https://stackoverflow.com/questions/14781471
复制相似问题