gpt4 book ai didi

java - 具有昂贵成员实例的 Guice Provider 是否应该使用 @Singleton 进行注释?

转载 作者:太空狗 更新时间:2023-10-29 23:02:24 26 4
gpt4 key购买 nike

Guice Providers 应该用 @Singleton 注释吗?我的理由:如果 Provider 正在向其他 Singleton 类提供一个对象,并且对象本身的创建成本相对较高,那么使用在其 @Inject -标记的构造函数,将其存储为成员并仅在 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/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com