Guice:Singleton.class和@Singleton之间的差异 [英] Guice: differences between Singleton.class and @Singleton

查看:189
本文介绍了Guice:Singleton.class和@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 same AImpl instance every time.
  • Injecting AImpl will retrieve a different AImpl every time, all of which are different than A's instance.
  • Injecting B will retrieve the same BImpl instance every time.
  • Injecting BImpl will also retrieve that same BImpl instance that B 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 same CImpl instance.
  • Injecting CImpl will create a new CImpl every time, unless CImpl has no injectable public zero-arg constructor—then the injection will fail.
  • Injecting D will always return the same DImpl instance.
  • Injecting DImpl will return a new instance every time, and each will be different than the one returned by D.
  • Injecting E will return the same EImpl instance every time.
  • Injecting EImpl will also retrieve that same instance E 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆