为什么CDIBean类的构造函数被多次调用



我用@ApplicationScoped注释了一个类。通过@Inject,我将该类的实例注入到几个@RequestScoped JAX-RS服务中:

@ApplicationScoped
public class MySingleton {
  MySingleton() {
    System.out(this + " created.");
  }
}
@RequestScoped
public class MyRS {
  @Inject MySingleton mySingleton;
  public void someMethod() {
    // do something with mySingleton
  }
}

基本上这很好用。Howeger,至少当我在WebSphere 8.5中运行它时,MySingleton的构造函数会被调用两次,从而产生类似的输出

my.package.MySingleton_$$_javassist_26@cddebf9b created.
my.package.MySingleton@e51e26d1 created.

我计划在构造函数中进行一些昂贵的初始化,这显然会执行两次。

我相信其中一个构造函数调用是为实际的"worker"实例生成某种代理。但是如何避免初始化代码被执行两次呢?在MySingleton的所有方法中进行延迟初始化的"解决方案"并不是很有吸引力。

容器也可以调用托管bean的构造函数来创建代理。因此,对于任何"真实"初始化,JavaEE都提供了注解@PostConstruct。在@ApplicationScoped bean中,容器只调用一次用@PostConstruct注释的方法:

@ApplicationScoped
public class MySingleton {
  MySingleton() {
    System.out(this + " created.");
  }
  @PostConstruct
  init() {
    System.out(this + " initd.");
  }
}

输出:

my.package.MySingleton_$$_javassist_26@cddebf9b created.
my.package.MySingleton@e51e26d1 created.
my.package.MySingleton@e51e26d1 initd.

相关问题:为什么使用@PostConstruct?

这是为您的singleton创建的javassist代理对象。singleton构造函数应该只在创建实际对象时调用。

相关内容

  • 没有找到相关文章

最新更新