Guice:Singleton.class和@Singleton之间的差异 [英] Guice: differences between Singleton.class and @Singleton
问题描述
在Guice中,有什么区别:
In Guice, what's the difference between:
// 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();
}
它们是否相同?你什么时候使用一个?在此先感谢。
Are they both the same? When would you use one versus the other? Thanks in advance.
推荐答案
它们几乎相同。 @Singleton
语法对于注释 @Provides
方法或注释类本身很有用(尽管我更喜欢保留我的模块内的范围注释)。
They are nearly identical. The @Singleton
syntax is useful for annotating @Provides
methods, or annotating the class itself (though I prefer to keep my scoping annotations inside modules).
不同之处在于哪个键标记为Singleton ,与关系不大@Singleton
与 Singleton.class
(或 Scopes.SINGLETON
, asEagerSingleton
, @Singleton
类注释,或 toInstance
隐式单例)等等使用默认语法变得容易。例如:
The difference lies in which key is marked Singleton, which has less to do with @Singleton
versus Singleton.class
(or Scopes.SINGLETON
, asEagerSingleton
, @Singleton
class annotations, or toInstance
implicit singletons) and more to do with what the default syntax makes easy. For example:
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
,但行为不同:
Above we've bound interface A
to class AImpl
, and interface B
to class BImpl
, but the behavior is different:
- 注入
A
将检索每次都是相同的AImpl
实例。 - 注入
AImpl
将检索不同的每次AImpl
,所有这些都与A
的实例不同。 - 注入
B
每次都会检索相同的BImpl
实例。 - 注入
BImpl
也将检索B
相同的BImpl
实例注入。
- Injecting
A
will retrieve the sameAImpl
instance every time. - Injecting
AImpl
will retrieve a differentAImpl
every time, all of which are different thanA
's instance. - Injecting
B
will retrieve the sameBImpl
instance every time. - Injecting
BImpl
will also retrieve that sameBImpl
instance thatB
injects.
如您所见,每个键都不同,如果只有接口与Singleton绑定,Guice将允许多个实现实例。如果您只注入 A
和 B
接口,则行为看起来完全相同,但是如果您注入接口和实现在相同的Injector中,您可能会看到不同的行为。
As you can see, each key is different, and Guice will allow multiple implementation instances if only the interface is bound with Singleton. If you only ever inject A
and B
interfaces, the behavior looks identical, but if you inject both interfaces and implementations from the same Injector, you may see differing behavior.
类似的逻辑适用于 @Provides
方法:
Similar logic goes for @Provides
methods:
- 注入
C
将始终返回相同的CImpl
实例。 - 每次注入
CImpl
都会创建一个新的CImpl
,除非CImpl
没有可注入的公共零参数构造函数 - 否则注入将失败。 - 注入
D
将始终返回相同的DImpl
实例。 - 注入
DImpl
每次都会返回一个新实例,每个实例都与D
返回的实例不同。 - 注入
E
每次都会返回相同的EImpl
实例。 - 注入
EImpl
也会检索到在同一个实例E
注入。
- Injecting
C
will always return the sameCImpl
instance. - Injecting
CImpl
will create a newCImpl
every time, unlessCImpl
has no injectable public zero-arg constructor—then the injection will fail. - Injecting
D
will always return the sameDImpl
instance. - Injecting
DImpl
will return a new instance every time, and each will be different than the one returned byD
. - Injecting
E
will return the sameEImpl
instance every time. - Injecting
EImpl
will also retrieve that same instanceE
injects.
这提供了一些灵活性。想象一下假设的缓存
,它保留了一定数量的最近检索到的对象,你想拥有 @User Cache
和 @Product Cache
都是可注射的。如果您 bind(Cache.class).in(Singleton.class)
,您将在对象之间共享一个Cache(以及任何裸 Cache
injections),而如果你 bind(Cache.class).annotatedWith(User.class).to(Cache.class).in(Singleton.class)
然后带注释的密钥保存在单一范围内,每个对象类型都有自己的缓存。
This provides some flexibility. Imagine a hypothetical Cache
that keeps a certain number of most-recently-retrieved objects, where you want to have @User Cache
and @Product Cache
both injectable. If you bind(Cache.class).in(Singleton.class)
, you will have one Cache shared between the objects (and any bare Cache
injections), whereas if you bind(Cache.class).annotatedWith(User.class).to(Cache.class).in(Singleton.class)
then the annotated key is kept in singleton scope and each object type will have its own cache.
这篇关于Guice:Singleton.class和@Singleton之间的差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!