guice中非单例的懒加载
Lazy load of non-singleton in guice
我在我的项目中使用 Guice 作为 DI,我想在我的 class 中对非单例对象进行延迟初始化。
我试图使用 Provider
,但每次我调用 get()
方法时它都会返回新实例。
public class MyClass {
@Inject
private Provider<Service> serviceProvider; //Service is NOT Singleton
public void meth1() {
Service s1 = serviceProvider.get();
}
public void meth2() {
Service s2 = serviceProvider.get();
}
//I want s1 and s2 to be the same object
}
Guice 可以做到吗,或者是否有任何其他做法可以做到这一点?
如果你需要 s1
和 s2
来引用同一个实例,那么你只需要一个 Service
的实例来引用 MyClass
的实例,并且简单地解析为 实例字段 :
public class MyClass {
@Inject
private Provider<Service> serviceProvider;
private Service service;
public void meth1() {
if (this.service == null) this.service = this.serviceProvider.get();
// use service
}
public void meth2() {
if (this.service == null) this.service = this.serviceProvider.get();
// use service
}
}
正如 Tavian 在评论中提到的那样,最好的解决方案是 Suppliers.memoize(serviceProvider::get)
,或一些等效的解决方案。 Suppliers (and Supplier) are in the Google utility library Guava, and since Java 8, Guava's Supplier extends the Java 8 functional interface Supplier,尽管 Java 8 不提供与 Suppliers 等效的内置功能。 serviceProvider::get
的规范对于使 Provider 在没有显式适配器的情况下充当 Supplier 是必要的,即使它们都指定了一个方法,即零参数 T get()
.
与 Google 的其他 DI 框架不同,Dagger, Supplier doesn't have a Lazy class to provide the local memoization you're looking for. Though you could do the kind of "check then set" behavior that tmarwen offers in , that strategy (as mentioned in their comment) is not thread-safe, while Suppliers.memoize 是明确的线程安全的。
虽然 Guava 提供了很多有用的功能,但您可能不想为单个方法添加一个全新的库。如果你确实需要没有完整库的线程安全,你可以看看 the Apache-licensed implementation here.
我在我的项目中使用 Guice 作为 DI,我想在我的 class 中对非单例对象进行延迟初始化。
我试图使用 Provider
,但每次我调用 get()
方法时它都会返回新实例。
public class MyClass {
@Inject
private Provider<Service> serviceProvider; //Service is NOT Singleton
public void meth1() {
Service s1 = serviceProvider.get();
}
public void meth2() {
Service s2 = serviceProvider.get();
}
//I want s1 and s2 to be the same object
}
Guice 可以做到吗,或者是否有任何其他做法可以做到这一点?
如果你需要 s1
和 s2
来引用同一个实例,那么你只需要一个 Service
的实例来引用 MyClass
的实例,并且简单地解析为 实例字段 :
public class MyClass {
@Inject
private Provider<Service> serviceProvider;
private Service service;
public void meth1() {
if (this.service == null) this.service = this.serviceProvider.get();
// use service
}
public void meth2() {
if (this.service == null) this.service = this.serviceProvider.get();
// use service
}
}
正如 Tavian 在评论中提到的那样,最好的解决方案是 Suppliers.memoize(serviceProvider::get)
,或一些等效的解决方案。 Suppliers (and Supplier) are in the Google utility library Guava, and since Java 8, Guava's Supplier extends the Java 8 functional interface Supplier,尽管 Java 8 不提供与 Suppliers 等效的内置功能。 serviceProvider::get
的规范对于使 Provider 在没有显式适配器的情况下充当 Supplier 是必要的,即使它们都指定了一个方法,即零参数 T get()
.
与 Google 的其他 DI 框架不同,Dagger, Supplier doesn't have a Lazy class to provide the local memoization you're looking for. Though you could do the kind of "check then set" behavior that tmarwen offers in
虽然 Guava 提供了很多有用的功能,但您可能不想为单个方法添加一个全新的库。如果你确实需要没有完整库的线程安全,你可以看看 the Apache-licensed implementation here.