Guice Providers 应该用 @Singleton
注释吗?我的理由:如果 Provider 正在向其他 Singleton 类提供一个对象,并且对象本身的创建成本相对较高,那么使用在其 @Inject中构造昂贵对象的 Singleton Provider 是否有意义
-标记的构造函数,将其存储为成员并仅在 getter 中返回已保存的全局变量?像这样:
@Singleton
public class MyProvider extends Provider<ExpensiveObject> {
private ExpensiveObject obj;
@Inject
public MyProvider() {
/* Create the expensive object here, set it to this.obj */
}
@Override
public ExpensiveObject get() {
return obj;
}
}
更新
让我在这里再澄清一点。这与我是否应该使用 @Singleton
或 .in(Singleton.class)
无关。这与创建对象的“缓存”有关。
假设对象创建需要多个 RPC 才能完成,例如反序列化 JSON 或发出 HTTP 请求。这可能需要相当长的时间。如果我要使用这个 Provider 多次注入(inject)类,那么只创建一次这样的对象不是很有意义吗?
另请注意,我必须能够使用 Provider,因为我需要能够注入(inject) Provider。
最佳答案
如果你的问题是你是否应该创建作用域提供者绑定(bind),或者你是否应该手动在你的提供者中缓存实例,那么真的,不要试图比 Guice 更聪明 :) 你真的不想做任何事情,只是在 get()
中创建昂贵的对象方法。简单测试用例:
public class MyProvider implements Provider<String> {
public String get() {
System.out.println("Called MyProvider.get()");
return "abcd";
}
}
public class MyModule extends AbstractModule {
protected void configure() {
bind(String.class).toProvider(MyProvider.class).in(Singleton.class);
}
}
Injector injector = Guice.createInjector(new MyModule());
String abcd1 = injector.getInstance(String.class); // Prints "Called MyProvider.get()
String abcd2 = injector.getInstance(String.class); // Prints nothing!
// Or, if you want, comment out above two lines and try the following:
Provider<String> abcdProvider = injector.getProvider(String.class);
abcdProvider.get(); // Prints "Called MyProvider.get()"
abcdProvider.get(); // Prints nothing
你看,因为消息只打印了一次,MyProvider.get()
方法也只被调用一次,正是因为 String
绑定(bind)在单例范围内。
这里要理解的关键概念是提供者和绑定(bind)不是独立的实体。每个绑定(bind)都有一个关联的提供程序(当您使用 to()
创建普通绑定(bind)时,会为您创建一个隐式提供程序)。这可以很容易地从 getProvider()
中观察到。方法签名 - 它接受 Class<T>
或 Key<T>
对于您想要获得的实际类(class),而不是对于您绑定(bind)的提供者。当您创建到特定提供程序的绑定(bind)时,您不配置此提供程序,而是配置绑定(bind)。 Guice 足够聪明,即使您使用显式提供程序也可以考虑作用域,因此您不需要重新发明轮子并推出自己的单例。
如果您的问题具体是关于 @Singleton
的用法注释(与 bind()
DSL 相反),那么我不知道它在提供者类中的存在是否会产生任何影响,但考虑到您应该使用 bind().toProvider()
无论如何绑定(bind)到这个提供者,我认为这并不重要。只需使用 in()
方法,肯定有用。
关于java - 具有昂贵成员实例的 Guice Provider 是否应该使用 @Singleton 进行注释?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20473606/