5

我用@ApplicationScoped 注释了一个类。使用@Inject,我将此类的实例注入到几个@RequestScopded 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.

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

我相信构造函数调用之一是为实际的“工人”实例生成某种代理。但是我怎样才能避免让我的初始化代码执行两次呢?在 MySingleton 的所有方法中进行延迟初始化的“解决方案”并不是很有吸引力。

4

2 回答 2

10

容器也可以调用托管 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.

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

于 2013-08-26T09:40:05.027 回答
0

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

于 2013-08-22T17:51:54.457 回答