2014-10-17 41 views
0

我正嘗試使用Java EE 6構建應用程序。開發是在TomEE 1.7上完成的。由於各種原因,我必須通過服務生產者創建大部分CDI託管對象。但是,當我這樣做時,不會調用已創建的Bean的註釋方法@PostConstruct。如果我將服務生產者排除在外,並讓CDI通過其構造函數直接創建對象,則它會被調用。這是正常的,或者是它的CDI提供的使用服務生產者的CDI PostConstruct

感謝

回答

1

這是正常行爲的錯誤TomEE自帶(開放WebBeans的)。當bean被容器初始化時,調用@PostConstruct方法。見Weld Reference

簡化只是一個小的事情在這個順序發生:

  • 首先,容器調用bean的構造函數(默認構造函數或一個註釋@Inject),來獲得實例
    這個bean。

  • 接下來,容器初始化bean的所有注入字段的值。

  • 接下來,容器調用bean的所有初始化方法(調用順序不可移植,不要依賴它)。
  • 最後,調用@PostConstruct方法(如果有的話)。

然而,在製作方法的情況下,你有充分的控制,對象是如何創建的,所以你可以自行調用任何需要的方法。注意,在生產者方法中,對象通常是使用new創建的,因此帶註釋的字段不會被初始化。再次檢查producer method documentation可能的解決方案(注入生產者方法,@New

+0

我把它直接在生產者調用@PostConstruct方法工作。我以前曾嘗試過,但無法完成,因爲該方法取決於其他注入生產的其他豆類的方法。發現生產者方法的論點填補了這個空白。 – 2014-10-20 06:52:05

0

似乎不好的做法使用生產者的一切 - 爲什麼你使用生產者,如果你的類用@PostConstruct註釋?

這樣做的一種方法是在生產者方法中使用創建上下文來提供引用,然後在該引用上調用post構造。下面是一些示例代碼,從Apache DeltaSpike,一套CDI擴展采取:

BeanProvider

BeanManager beanManager = getBeanManager(); 

    CreationalContext creationalContext = beanManager.createCreationalContext(null); 

    AnnotatedType annotatedType = beanManager.createAnnotatedType(instance.getClass()); 
    InjectionTarget injectionTarget = beanManager.createInjectionTarget(annotatedType); 
    injectionTarget.inject(instance, creationalContext); 
    injectionTarget.postConstruct(instance); 
+0

我使用了一個生產者,因爲在UI bean中注入的大多數組件都有兩種風格,創建的內容取決於運行時參數。你的示例代碼似乎將注入的bean的後期構建與注入點相關聯,因此對於多個注入點,我需要對哪個注入點調用post構建進行一些管理。 – 2014-10-20 06:30:44

+0

我不確定你的意思。是什麼讓你想到這個?例如,這是一個生產者方法的內容,一旦你實例化了你的實例。 'InjectionTarget'只是一個CDI中的API,允許您在託管對象上調用PostConstruct或PreDestroy方法。 – 2014-10-20 10:35:02

+0

對不起,我的解釋只是猜測。我假設InjectionTarget表示創建的實例注入的bean,並且代碼在注入發生時運行。我的錯。當我有一段時間的時候,我會仔細看看DeltaSpike,這似乎是一個有價值的投資 – 2014-10-22 07:09:38