關于session bean的一些問題
EJB里面,session bean是占了挺重要的地位的,一些重要的事情都是交給session bean來處理的
session BEAN一般用于操作一些對外的方法,供客戶調用.會話BEAN分兩種,一種 是有狀態的會話BEAN,一種 是無狀態的會話BEAN,它們有什么不同呢?
有狀態的會話BEAN,會記錄每一個調用者的狀態,每個人都有一個自己的實例,相比之下,它比較耗內存.一般用于做專用的事情
無狀態的會話BEAN,則不會記錄每一個調用者的狀態,所有人共有一個實例,所以它不耗內存,一般用于做一些通用的事情
會話BEAN中有一種叫定時服務,并不是所有的會話BEAN都可以有定時服務器,而只有無狀態的會話BEAN可以有定時的服務,如果調用的是有狀態的會話BEAN的話,那么運行時就會出異常,不知道是不是有狀態的會話BEAN不允許有定時服務.對于會話BEAN,我們可以掌握它的生命周期
EJB容器創建和管理session bean實例,有些時候,你可能需要定制 session bean的管理過程。例如,你可能想在創
建session bean實例的時候初始化字段變量,或在bean實例被銷毀的時候關掉外部資源。上述這些,你都可能通過
在 bean 類中定義生命周期的回調方法來實現。這些方法將會被容器在生命周期的不同階段調用(如:創建或銷
毀時)。通過使有下面所列的注釋,EJB 3.0允許你將任何方法指定為回調方法。這不同于 EJB 2.1,EJB 2.1中,
所有的回調方法必須實現,即使是空的。EJB 3.0中,bean可以有任意數量,任意名字的回調方法。
·@PostConstruct:當bean對象完成實例化后,使用了這個注釋的方法會被立即調用。這個注釋同時適用于
有狀態和無狀態的會話bean。
·@PreDestroy:使用這個注釋的方法會在容器從它的對象池中銷毀一個無用的或者過期的 bean 實例之前調
用。這個注釋同時適用于有狀態和無狀態的會話 bean。
·@PrePassivate:當一個有狀態的session bean實例空閑過長的時間,容器將會鈍化(passivate)它,并把它的
狀態保存在緩存當中。使用這個注釋的方法會在容器鈍化bean實例之前調用。這個注釋適用于有狀態的會話bean。
當鈍化后,又經過一段時間該 bean 仍然沒有被操作,容器將會把它從存儲介質中刪除。以后,任何針對該 bean
方法的調用容器都會拋出例外。
·@PostActivate:當客戶端再次使用已經被鈍化的有狀態 session bean 時,新的實例被創建,狀態被恢復。
使用此注釋的session bean會在bean的激活完成時調用。這個注釋只適用于有狀態的會話 bean。
·@Init:這個注釋指定了有狀態session bean初始化的方法。它區別于@PostConstruct注釋在于:多個@Init
注釋方法可以同時存在于有狀態session bean 中,但每個 bean實例只會有一個@Init注釋的方法會被調用。這取
決于bean是如何創建的(細節請看EJB 3.0規范)。@PostConstruct在@Init之后被調用。
另一個有用的生命周期方法注釋是@Remove,特別是對于有狀態 session bean。當應用通過存根對象調用使用了
@Remove注釋的方法時,容器就知道在該方法執行完畢后,要把 bean實例從對象池中移走。
這里要注意的一點是,對于無狀態的會話BEAN,即使你調用了標記為@Remove的方法,這個會話BEAN依然有效,所以,這個注釋應該用在有狀態的會話BEAN中,這樣當你調用了它所標記的方法 后,再調用這個會話BEAN的其它方法就會拋出一個異常
javax.ejb.EJBNoSuchObjectException: Could not find Stateful bean:它會說找不到這個有狀態的會話BEAN了,因為這個時候經過你調用了標記為@Remove的方法后,EJB容器已經將它銷毀了,以后的任何調用都是無效的了,這樣有利于我們更好的掌握會話BEAN的生命周期,免得產生很有有狀態的會話BEAN的時候,過多的消耗服務器的內存.