@Produces 不是return cdi代理,而是真实实例
@Produces does not return cdi proxy, but real instance
我有一个class
@RequestScoped
public class AFactory {
private final HttpServletRequest request;
protected AFactory () {
this.request = null;
}
@Inject
public AFactory (HttpServletRequest request) {
this.request = request;
}
@Produces
public A getA() {
int random = ...;
A a = new A(request);
a.setRandom(random);
return a;
}
}
我明白了,因为我在做 new A(),所以我 return 真实的实例。
这是使用生产者的预期方式吗?
有没有办法return代理实例?
CDI 安装 proxies for beans of all scopes except for the @Dependent
pseudo scope。每当需要获取 bean 的(新)实例时,CDI 就会调用 @Produces
注释方法(简称 producer)。然后将此实例放入相应范围的某个池中。
代理将始终从池中 return bean-instance。尝试向生产者方法添加一些调试消息以查看它被调用的频率。 @ApplicationScoped
bean 的生产者应该只被调用一次,而 @RequestScoped
生产者应该在每个请求中被调用一次。
在上面的示例中,没有为生产者方法指定范围(工厂范围 class 未用于生产者方法),因此将使用默认范围 (@Dependent)。这意味着(因为这个范围没有使用代理),每次 CDI 发现 @Inject A
时都会注入一个新实例。另请参阅此 Question and Answer 和参考文档以了解更多详细信息。
所以对于你的具体问题:
- 观察到的行为是预期的
- 仅当范围不是默认范围
@Dependet
时才会使用代理。
我有一个class
@RequestScoped
public class AFactory {
private final HttpServletRequest request;
protected AFactory () {
this.request = null;
}
@Inject
public AFactory (HttpServletRequest request) {
this.request = request;
}
@Produces
public A getA() {
int random = ...;
A a = new A(request);
a.setRandom(random);
return a;
}
}
我明白了,因为我在做 new A(),所以我 return 真实的实例。
这是使用生产者的预期方式吗?
有没有办法return代理实例?
CDI 安装 proxies for beans of all scopes except for the @Dependent
pseudo scope。每当需要获取 bean 的(新)实例时,CDI 就会调用 @Produces
注释方法(简称 producer)。然后将此实例放入相应范围的某个池中。
代理将始终从池中 return bean-instance。尝试向生产者方法添加一些调试消息以查看它被调用的频率。 @ApplicationScoped
bean 的生产者应该只被调用一次,而 @RequestScoped
生产者应该在每个请求中被调用一次。
在上面的示例中,没有为生产者方法指定范围(工厂范围 class 未用于生产者方法),因此将使用默认范围 (@Dependent)。这意味着(因为这个范围没有使用代理),每次 CDI 发现 @Inject A
时都会注入一个新实例。另请参阅此 Question and Answer 和参考文档以了解更多详细信息。
所以对于你的具体问题:
- 观察到的行为是预期的
- 仅当范围不是默认范围
@Dependet
时才会使用代理。