@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 时才会使用代理。