head first ejb(session bean)

session bean分爲stateful bean與stateless bean, 主要分別爲stateful bean可以保存當前服務對象的狀態, 而且是每個服務對象都會有爲自己服務的bean. stateless bean則不保存服務對象的狀態, 只是根據服務對象所要求的操作提供服務, 可以爲多個對象提供報務.

session bean要實現SessionBean, 然後加上自己的業務方法. 它是真正的業務服務的提供者(其實應當是POJO的EJB封裝). 這些業務方法應該與其返回給客戶的遠程接口的方法名相同, 除了不能有RemoteException之外.

session bean生活在ejb容器的控制中, 處在ejb object的保護之下, 並不直接與所服務的客戶進行交流. 對於一個session bean來說, 其生命週期主要由建立, 處理服務, 鈍化, 激活與移除組成. stateful bean一般會完整的經歷這些過程, 但對於stateless bean來說, 由於其不保存客戶的狀態信息, 所以沒有鈍化與激活這兩個過程.

在客戶要求某個服務後, 容器負責將對應提供服務的session bean建立. 順序是constructor setSessionContext ejbCreate. 然後通過ejbPassivate與ejbActivate進行鈍化與激活. 最後再通過ejbRemove通知bean將被移除.

容器 利用setSessionContext(SessionContext sc) 方法將自己的session context傳給session bean, 使其可以通過SessionContext得到自己所在容器的事務/安全/資源等環境信息. 但在這個方法時, bean實際上還沒真正在容器中成爲session bean, 所以在這個方法中只能將對SessionContext的引用保存下來, 留給後面的方法使用. 當然在這個方法中, bean已經可以訪問環境了, 比如使用jndi, 但不能使用jndi給出的對象. 所以個人認爲還不如放到ejbCreate()中再說.

容器利用ejbCreate()方法通知bean它現在成爲了session bean了. 這給bean一個機會, 在這個方法中真正的引用環境來初始化自己. 但在這個方法中, 由於不是對應的業務服務, 所以無法進行CMT方法的操作. 對於stateless bean來說, 只需要一個ejbCreate()方法, 而且容器也只會調用這個方法來進行通知. 而對於stateful bean來說, 可以提供多個ejbCreate方法, 而且這個方法可以以ejbCreateXXXX的形式存在, 當然對應的home就要聲明成createXXXX的形式.

對於 stateful bean來說, 由於其保存了客戶的信息, 所以不能同時對多客戶提供服務, 如果它服務的客戶在一段時間內沒有要求其服務又不明確表示可以移除, 那麼容器將會使用java的流機制對這個bean進行保存, 這一過程又叫鈍化. 等到客戶又有要求提供服務時再進行激活. 容器在進行鈍化時, 會調用ejbPassivate()通知對應的bean. 而bean應當在這個方法中將其持有的不可流化的資源關閉,或使用自己的方法將其保存, 等到激活時再打開. 實際上由於容器對鈍化的bean實行的是, 如果超時就將其拋棄的政策而不會調用ejbRemove, 所以在ejbPassivate時, 應當將不能被jvm的gc收集的資源關閉. 對於激活, 容器會通過ejbActivate()來通知bean, 所作的事情與ejbPassivate()相反.

容器在移除session bean時, 會調用ejbRemove(). 在這個方法裏, session bean可以進行其的資源的釋放工作. 而且j2ee的規範要求session bean不能有finalize方法, 所以只有這個方法可以進行讓其進行這方面的工作了(其實ejbPassivate也要進行這方法的工作, 只是沒這麼明顯而已). 但在下列情況下, 容器不會調用ejbRemove: session bean在鈍化中超時, 容器崩潰, session bean的業務方法拋出了system exception(runtime exception). 這時, 資源的關閉就是你的問題了(汗, 真是規範定義者的風度啊).
發佈了48 篇原創文章 · 獲贊 0 · 訪問量 14萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章