全部
我不知道 JSR-330 中的 Inject 和 Provider 有什么区别。我正在使用 google guice,并且每天都在使用@Inject
,而且我知道在 JSR-330 中,它具有Provider<T>
.
我的问题是
- 是什么意思
Provider<T>
? - 什么时候可以当用户
Provider<T>
? - 有什么区别
@Inject
?
提前致谢。
全部
我不知道 JSR-330 中的 Inject 和 Provider 有什么区别。我正在使用 google guice,并且每天都在使用@Inject
,而且我知道在 JSR-330 中,它具有Provider<T>
.
我的问题是
Provider<T>
?Provider<T>
?@Inject
?提前致谢。
一切都已经在javadoc中进行了解释,我引用:
与
T
直接注入 (仅隐式使用@Inject
)相比,注入Provider<T>
能够:
- 检索多个实例。
- 实例的惰性或可选检索。
- 打破循环依赖。
- 抽象范围,以便您可以从包含范围内的实例中查找较小范围内的实例。
#1 的示例:
在这里,您从同一个提供者那里获得了几个实例,Seat
因此它被用作工厂。
class Car {
@Inject
Car(Provider<Seat> seatProvider) {
Seat driver = seatProvider.get();
Seat passenger = seatProvider.get();
...
}
}
#2 的示例:
在这里,您使用提供程序来避免直接创建类的实例,MyClassLongToCreate
因为我们知道这是一个缓慢的操作,因此我们将通过该get
方法仅在需要时才懒惰地获取它。
class MyClass {
@Inject
private Provider<MyClassLongToCreate> lazy;
...
}
#3 的示例:
这是一个循环依赖,容器无法轻易解决,因此某些容器可能会抛出异常,因为它们不知道如何自己解决。
class C1 {
private final C2 c2;
@Inject
C1(C2 c2) {
this.c2 = c2;
...
}
}
class C2 {
private final C1 c1;
@Inject
C2(C1 c1) {
this.c1 = c1;
...
}
}
为了修复它,我们Provider
在至少一个构造函数上使用 a 来打破循环依赖,如下所示:
class C1 {
private final Provider<C2> c2;
@Inject
C1(Provider<C2> c2) {
this.c2 = c2;
...
}
}
这将允许容器完全创建C1
first 的实例(因为我们实际上不需要创建实例C2
来注入 的提供者C2
)一旦完成,容器将能够C2
从C1
.
#4 的示例:
在这里,您有一个C2
作用域为会话的类,它依赖于C1
它的作用域为请求,我们使用提供程序来允许我们获取与C1
当前请求相对应的实例,因为它将从一个请求更改为另一个请求。
@RequestScoped
public class C1 {
...
}
@SessionScoped
public class C2 {
@Inject
private Provider<C1> provider;
...
public void doSomething() {
// Get the instance corresponding to the current request
C1 c1 = provider.get();
...
}
}