Java Guice:Singleton.class和@Singleton之间的区别
在Guice中,以下两者之间的区别是什么:Java Guice:Singleton.class和@Singleton之间的区别,java,dependency-injection,singleton,guice,Java,Dependency Injection,Singleton,Guice,在Guice中,以下两者之间的区别是什么: // Inside your AbstractModule subclass: @Override public void configure() { bind(Service.class).to(ServiceImpl.class).in(Singleton.class); } 以及: 他们都一样吗?你什么时候会用一个来对比另一个?提前谢谢。它们几乎一模一样。@Singleton语法对于注释@提供的方法或注释类本身非常有用(尽管我更喜欢将作
// Inside your AbstractModule subclass:
@Override
public void configure() {
bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
}
以及:
他们都一样吗?你什么时候会用一个来对比另一个?提前谢谢。它们几乎一模一样。
@Singleton
语法对于注释@提供的
方法或注释类本身非常有用(尽管我更喜欢将作用域注释保留在模块中)
区别在于哪个键被标记为Singleton,这与@Singleton
与Singleton.class
相比关系不大(或者作用域.Singleton
,asagersingleton
,@Singleton
类注释,或者到instance
隐式Singleton)还有更多的工作要做,默认语法使之变得简单。例如:
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
,但行为不同:
- 注入
将每次检索相同的A
实例AImpl
- 每次注入
将检索不同的AImpl
,所有这些都不同于AImpl
的实例a
- 注入
将每次检索相同的B
实例BImpl
- 注入
还将检索与BImpl
注入相同的B
实例BImpl
A
和B
接口,行为看起来是相同的,但是如果从同一个注入器注入两个接口和实现,则可能会看到不同的行为
类似的逻辑适用于@提供了方法:
- 注入
C
将始终返回相同的CImpl
实例
- 每次注入
CImpl
都将创建一个新的CImpl
,除非CImpl
没有可注入的公共零参数构造函数,否则注入将失败
- 注入
D
将始终返回相同的DImpl
实例
- 注入
DImpl
将每次返回一个新实例,并且每个实例都不同于D
返回的实例
- 注入
E
将每次返回相同的EImpl
实例
- 注入
EImpl
也将检索相同的实例E
injects
这提供了一些灵活性。设想一个假设的缓存
,它保存一定数量的最近检索的对象,您希望@User Cache
和@Product Cache
都是可注入的。如果bind(Cache.class).in(Singleton.class)
,对象之间将共享一个缓存(以及任何裸Cache
注入),而如果bind(Cache.class).annotatedWith(User.class).to(Cache.class).in(Singleton.class)
然后带注释的键保存在单例范围内,每个对象类型都有自己的缓存。我遇到过这样的情况,它们的行为似乎有所不同。使用bind语句并没有限制为仅使用1个实例。不过,使用@Singleton它还是有效的。@EFreak:更新了答案。这并不完全是语法上的差异,但从新的角度来看这个问题,这里有一些微妙之处。非常感谢!这正是我昨天面临的问题。不过,我有一个编辑建议。将更新答案。
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(); }
}