首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Guice: Singleton.class和@Singleton之间的区别

Guice: Singleton.class和@Singleton之间的区别
EN

Stack Overflow用户
提问于 2013-02-09 05:14:16
回答 1查看 24.7K关注 0票数 25

在Guice中,以下命令有什么区别:

代码语言:javascript
复制
// Inside your AbstractModule subclass:
@Override
public void configure() {
    bind(Service.class).to(ServiceImpl.class).in(Singleton.class);
}

和:

代码语言:javascript
复制
@Override
public void configure() {
    bind(Service.class).to(ServiceImpl.class);
}

@Provides @Singleton
public ServiceImpl providesService() {
    return new ServiceImpl();
}

它们都是一样的吗?什么时候你会使用一种而不是另一种呢?提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-09 10:36:55

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

区别在于哪个键被标记为单例,这与@SingletonSingleton.class (或Scopes.SINGLETONasEagerSingleton@Singleton类注释或toInstance隐式单例)的关系较小,而更多地与默认语法的简单性有关。例如:

代码语言:javascript
复制
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.

  • Injecting

  • Injecting A将检索相同的AImpl实例每个time.

  • Injecting AImpl每次都将检索不同的AImpl,所有这些都不同于AB BImpl将检索相同的BImpl实例每个time.

  • Injecting BImpl还将检索B注入的相同<BImpl>D31实例。

正如您所看到的,每个键都是不同的,如果仅将接口与Singleton绑定,则Guice将允许多个实现实例。如果您只注入AB接口,行为看起来是相同的,但是如果您同时注入来自同一个Injector的接口和实现,您可能会看到不同的行为。

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

  • Injecting C将始终返回相同的代码CImpl CImpl每次都会创建一个新的代码,除非代码没有可注入的公共零参数构造函数-那么注入将始终返回相同的代码instance.
  • Injecting < DImpl >D53DImpl>每次都将返回一个新的实例,并且每个实例都与D.
  • Injecting返回的实例不同,每个time.
  • Injecting 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),那么带注释的键将被保存在单例作用域中,并且每种对象类型都将拥有自己的缓存。

票数 47
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14781471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档