2013-08-22 59 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代理對象。在創建實際對象時,應該只調用單體構造器。

相關問題