【问题标题】:Weld @Inject ApplicationScope bean creates new instance in every inject pointWeld @Inject ApplicationScope bean 在每个注入点创建新实例
【发布时间】:2013-03-20 00:49:18
【问题描述】:

我正在尝试使用 Weld 来了解 CDI。得到下一个结构:

@ApplicationScoped
public class MainFacade {

    @Inject
    private FooFacade fooFacade;

    private static int ins=0;

    public MainFacade() {
        super();
        ins++;
        System.out.println("MainFacade instance = "+ins);
    }

    public FooFacade getFooFacade() {
        return fooFacade;
    }
}

FooFacade 也是@ApplicationScope。

当应用程序启动时,我得到一个 MainFacade 实例 = 1。当我将它注入其他类(GWT RPC servlet)并调用 mainFacade.getFooFacade() 时,将创建 MainFacade 的新实例以及 fooFacade 的新实例.

认为 Weld 会在我注入它的任何地方返回相同的应用程序范围 bean 实例。我做错了什么?

【问题讨论】:

  • 你如何确定它是一个新实例?可能是注入了不同的代理。
  • 你不会说出你在标准输出上看到的任何东西。

标签: java cdi weld jsr299


【解决方案1】:

当您使用@ApplicationScoped Weld 时,Weld 也会创建一个调用构造函数的代理,specification here

【讨论】:

  • 我无法解析这个答案。可以改写吗?
【解决方案2】:

我认为这个测试不能很好地验证应用程序范围的 bean 是否真的是“单例”。

如果您将此 bean 注入到其他 bean 中,Weld 将创建一个代理,该代理将处理对正确实例的所有调用的委托。例如,如果您将请求范围的 bean 注入到会话范围的 bean 中,这一点尤其重要。

代理将基本上扩展MainFacade,这是必需的,否则代理无法注入到发生注入的字段中。创建代理实例时,将执行 bean 的默认构造函数。由于 Weld 将创建许多代理,您会在控制台中看到多个日志。您可以通过在构造函数中添加类似这样的内容来验证这一点:

System.out.println("Type: "+this.getClass().getName());

【讨论】:

  • 谢谢,我之前自己发现的,但是你的帖子涵盖了所有方面。
猜你喜欢
  • 2014-05-26
  • 2011-12-05
  • 2018-06-25
  • 2011-10-21
  • 1970-01-01
  • 2018-02-02
  • 2012-03-02
  • 1970-01-01
  • 2014-02-16
相关资源
最近更新 更多