2013-08-22 62 views
3

我用@ApplicationScoped注释了一个类。使用@Inject我得到这个类的实例注入到几个@RequestScopded JAX-RS服务:为什么多次调用CDI bean类的构造函数

@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的构造函数被调用两次,导致输出像

[email protected] created. 
[email protected] created. 

我打算做一些昂贵的初始化在构造函数中,这显然是执行两次。

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

+0

只是盲目的猜测,但尝试使用@ PostConstruct方法来查看它是否被调用两次。 –

+0

@@ PostConstruct仅被调用一次,这正是我所需要的。有了这个提示,我还发现了一个相关的问题[why-use-postconstruct]。如果你发布这个答案,我会接受它。谢谢,@阿德里安。 –

+0

您应该使用接口来代替具体的类来注入。 –

回答

6

托管bean的构造函数也可以由容器调用,用于创建代理。对于任何“真正的”初始化,Java EE因此提供注解@PostConstruct。在@ApplicationScoped豆与@PostConstruct注释的方法是由容器调用一次:

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

输出:

[email protected] created. 
[email protected] created. 
[email protected] initd. 

相关问题:Why use @PostConstruct?

0

这是一个为您的单例创建的javassist代理对象。在创建实际对象时,应该只调用单体构造器。

相关问题