代码之家  ›  专栏  ›  技术社区  ›  Gerhard

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

  •  5
  • Gerhard  · 技术社区  · 12 年前

    我已经用@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的所有方法中进行延迟初始化的“解决方案”并不是很有吸引力。

    2 回复  |  直到 9 年前
        1
  •  10
  •   Community Mohan Dere    9 年前

    容器也可以调用托管bean的构造函数来创建代理。因此,对于任何“真实”的初始化,Java EE都会提供注释@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.
    

    相关问题: Why use @PostConstruct?

        2
  •  0
  •   Robert Höglund    12 年前

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