2009-07-10 59 views
3

我正在JBoss上試驗EJB3,開發一個無狀態bean。基本上,一旦模塊已經部署,我需要執行一些與加載應用程序設置相關的操作。 爲此,我已經將一種方法註釋爲@PostConstruct,就我所知,API指示容器在部署bean之後和服務之前調用它。 (正確嗎?) 現在,我很困惑,因爲從那個方法的日誌看起來並不是簡單地在部署之後調用每個被暴露的方法之前調用。 我只需要調用一次該方法,而不是每次接到呼叫。最好的方法是什麼?java ejb3 @PostConstruct

在此先感謝

亞歷山德羅Ilardo

+0

我認爲Tim明白了,容器並不是每次都在SAME EJB實例上調用PostConstruct註釋的方法,但是它實際上爲它接收到的每個調用實例化一個新的EJB實例,可能是由於某些池設置。 – AleIla 2009-07-11 11:40:22

+0

不知道在這個特定情況下它是否會有所幫助,但是如果您使用社區版本的JBoss(例如5.1 AS),請確保通過安裝來自http://www.jboss的最新EJB3插件將其升級爲使用最新的EJB3代碼。組織/ EJB3。付費版本的JBoss會自動支付,但對於社區您需要手動升級它。 – 2009-10-06 10:08:14

回答

2

無狀態Bean應該只是 - 無狀態。這意味着在使用中,您不應該能夠告訴或關心該bean是從池中提取還是根據您的請求構建。我很難設想PostConstruct如何應用於無狀態環境,因爲我總是使用該函數來完成構建bean的狀態。顯然,JBoss要麼放棄無狀態bean的池化,並且每次構建新鮮的bean,要麼使用池化,像每次重建它們(因爲它們不應該攜帶狀態信息)。我其實有點驚訝,它根本調用PostConstruct。

+14

無狀態僅僅意味着「沒有對話狀態」,它並不意味着沒有任何狀態。他們幾乎肯定有合作者對象,並且可以使用@PostConstruct來初始化這些對象。 – skaffman 2009-07-10 10:58:45

0

由應用程序服務器來管理EJB的生命週期。它可能會決定在任何合適的時候構建,初始化和拆除bean。這可能是每個對無狀態bean的調用都在你的bean類的新實例上,儘管這看起來像是一個關閉的事情。

應用服務器是在同一個對象實例上多次調用@PostConstruct方法,還是每次都在不同的實例上調用?嘗試在構造函數和@PostConstruct方法內粘貼日誌語句。

0

你在游泳池裏有多少個SLSB?根據容器的不同,@PostConstruct在第一個客戶端訪問它之前可能不會被調用(對JBoss不確定),所以這可能是它看起來像是在每次訪問時的原因。在調用你的方法之後,看看它是否停止調用你的構造後方法,這將是有趣的,等於你的池大小的次數。

如果您在後構建方法中執行一些昂貴的操作,那麼可能會在啓動時在SFSB中執行這些操作,並在構建後將SFSB「注入」SLSB。

1

首先調用PostConstruct,然後在bean上調用第一個方法。如果沒有方法被調用,則不會調用任何後期構造。

其次,您可以在PreDestory方法中執行反動作來消除副作用。

無論如何你必須執行哪種動作?

0

PostConstruct在客戶端運行biz方法之前被調用。這意味着如果bean沒有被合併,容器將實例化bean,做注入,調用@PostConstruct方法,然後允許biz方法運行。

在彙集的情況下,每次從池中取出bean時都會運行@PostConstruct方法。對於無狀態bean,這將在每個方法調用之間進行。有了Stateful bean,這將在客戶端查找或注入之後進行。

如果您需要在應用程序部署上運行某些東西,您的選擇將取決於您擁有的Java EE版本。

對於Java EE 6,您可以在包含@PostConstruct方法的@Singleton EJB上使用@Startup。

對於Java EE 5和以前的版本,您必須在Web歸檔中使用ServletContextListener。如果需要,您可以讓ServletContextListener調用EJB。

但是,什麼可能是一個更重要的問題是你想在哪裏加載這些應用程序設置?如果您正在處理非集羣單JVM配置,那麼您可能需要將它們加載到某種類型的單例中。在Java EE 5中,您必須自己實現單例設計模式,或者在EE 6中使用@Singleton EJB類型。