java - Guice:Singleton.class 和@Singleton 的区别

标签 java dependency-injection singleton guice

在 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();
}

它们是一样的吗?您什么时候会使用一个与另一个?提前致谢。

最佳答案

它们几乎相同。 @Singleton 语法对于注释 @Provides 方法或注释类本身很有用(尽管我更喜欢将范围注释保留在模块中)。

区别在于哪个键标记为Singleton,与@SingletonSingleton.class(或Scopes.SINGLETONasEagerSingleton@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(); }
}

上面我们已经将接口(interface) A 绑定(bind)到类 AImpl,将接口(interface) B 绑定(bind)到类 BImpl,但是行为不同:

  • 每次注入(inject) A 都会获取相同的 AImpl 实例。
  • 每次注入(inject)AImpl都会获取不同的AImpl,所有这些都与A的实例不同。
  • 每次注入(inject) B 都会获取相同的 BImpl 实例。
  • 注入(inject) BImpl 还将检索 B 注入(inject)的相同 BImpl 实例。

如你所见,每个key都是不同的,只要接口(interface)绑定(bind)了Singleton,Guice就会允许多个实现实例。如果你只注入(inject) AB 接口(interface),行为看起来是相同的,但如果你从同一个注入(inject)器注入(inject)接口(interface)和实现,你可能会看到不同的行为。

类似的逻辑适用于 @Provides 方法:

  • 注入(inject) C 将始终返回相同的 CImpl 实例。
  • 每次注入(inject) CImpl 都会创建一个新的 CImpl,除非 CImpl 没有可注入(inject)的公共(public)零参数构造函数——那么注入(inject)将失败.
  • 注入(inject) D 将始终返回相同的 DImpl 实例。
  • 每次注入(inject)DImpl都会返回一个新的实例,每个实例都与D返回的实例不同。
  • 注入(inject) E 每次都会返回相同的 EImpl 实例。
  • 注入(inject) EImpl 也将检索 E 注入(inject)的相同实例。

这提供了一些灵 active 。想象一个假设的 Cache,它保留一定数量的最近检索的对象,您希望在其中拥有 @User Cache@Product Cache都可以注入(inject)。如果您bind(Cache.class).in(Singleton.class),您将在对象之间共享一个缓存(以及任何裸Cache 注入(inject)),而如果您bind(Cache.class).annotatedWith(User.class).to(Cache.class).in(Singleton.class) 然后带注释的键保存在单例范围内,每个对象类型都有它的自己的缓存。

关于java - Guice:Singleton.class 和@Singleton 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14781471/

相关文章:

Java 图形/基本游戏循环

java - 是否可以在运算符之前和之后剪切字符串?

extjs - 为什么我的 ExtJS 单例不起作用?

python - 将 Singleton 实现为元类,但用于抽象类

android - 如何将消息从类发送到 Activity 并向后发送

java - 尝试用 Java 实现 DFS

java - 如果在 StringBuffer(或 StringBuilder)上连续调用 append() 而不重用目标变量,我如何提高性能

java - 如何将属性值注入(inject)使用注释配置的 Spring Bean?

android - Dagger 2 无法解析符号 'DaggerAppComponent'

c# - 如何将 Func<T> 用作注入(inject)属性