EJB初級篇--EJB組件之會話Bean
來源:程序員人生 發布時間:2015-01-16 08:07:34 閱讀次數:3439次
上篇博文中我們已詳解介紹了甚么是EJB。其實最簡單的說:EJB就是運行在獨立服務器上的組件,客戶端是通過網絡對EJB對象進行調用的。而我們常說的企業Bean組件可以分為3種類型:會話Bean、消息驅動Bean和實體Bean。根據利用設計的不同,開發者可以選擇合適利用的組件類型。下面幾篇博文中我會為大家分別詳細的介紹這3種企業Bean組件。本篇博文則就先來介紹介紹會話Bean吧。
首先來介紹1下,甚么是會話Bean。會話Bean能夠完成客戶所要求的業務操作,它是含有業務邏輯的可重用組件,并能夠用于業務進程。簡單1句話:會話Bean就是用來實現業務邏輯的。
下面就詳細介紹會話Bean的主要內容,包括以下兩點:1是會話Bean的生命周期;2則是會話Bean的子類型。
-----------------------------------生 命 周 期-----------------------------------
先由1個例子引入:如果客戶端代碼調用用于完成“登錄登記”的會話Bean,則EJB容器需要完成會話Bean組件實例的創建。在后續操作中,如果客戶不再與該實例交互,利用服務器有可能會燒毀它。也就是說:會話Bean實例開始于客戶取得其援用時,而終止于客戶會話的終結。映照到會話Bean的生命周期,可以說:客戶會話(Client
Session)的延續期就決定了使用中的會話Bean的存活期,也就是生命周期。而1般情況下,客戶會話的延續期是比較短的,所以會話Bean的實例也是存活短暫的對象。
知道了會話Bean的生命周期后,那末操作會話Bean生命周期的又是甚么呢?答案就是EJB容器。不單單是會話Bean,EJB容器管理著EJB全部組件的生命周期。例如客戶超時,EJB容器將會燒毀會話Bean實例。
-----------------------------------子 類 型--------------------------------------
會話Bean存在兩種子類型:無狀態會話Bean和有狀態會話Bean,用于建模不同類型的會話。
1、無狀態會話Bean
無狀態會話Bean適用于只需單個要求會話便可完成的業務進程。這樣,EJB組件不需要保護方法調用間的狀態變更信息。
為了實現有效的Bean實例處理,EJB容器常常會使用實例池技術。下圖是無狀態會話Bean的實例池。我們可以清晰的導出無狀態會話Bean的內部機制。

圖1.1
由于無狀態會話Bean不含會話狀態,因此同1無狀態會話Bean類的所有實例對客戶而言都是等效的。而且無狀態會話Bean不保存歷史會話信息,所以它對調用其本身的客戶也其實不關注。因此,任何無狀態會話Bean都能夠服務任何客戶要求。由于這些無狀態會話Bean都是1樣的。
了解了原理以后,來1個很簡單的小Demo來加深對無狀態會話Bean的理解吧。首先是EJB的服務器端:
/**
* @ClassName: 無狀態會話Bean Demo接口類
* @Description: EJB
服務器端接口類
* @author 孫麗端
* @date 2014年11月28日20:22:51
*/
package com.tgb.ejb;
public interfaceStatelessEjb {
publicvoid compute(int i);
publicint getResult();
}
/**
* @ClassName: 無狀態會話Bean Demo實現類
* @Description: EJB
服務器端實現類
* @author 孫麗端
* @date 2014年11月28日20:22:51
*/
package com.tgb.ejb;
importjavax.ejb.Remote;
importjavax.ejb.Stateless;
@Stateless
@Remote
public classStatelessEjbBean implements StatelessEjb {
privateint state;
@Override
publicvoid compute(int i) {
state= state +i;
}
@Override
publicint getResult() {
//TODO Auto-generated method stub
return state;
}
其次來看看EJB的客戶端調用代碼實現,客戶端調用的是服務器端接口類的方法:
/**
* @ClassName: 無狀態會話Bean Demo客戶端類
* @Description: EJB客戶端類
* @author 孫麗端
* @date 2014年11月28日20:22:51
*/
package com.tgb.ejb;
importjavax.naming.InitialContext;
importjavax.naming.NamingException;
public classStatelessEjbClient {
publicstatic void main(String[] args) throws NamingException {
InitialContextcontext = new InitialContext();
StatelessEjbejb1 =(StatelessEjb)context.lookup("StatelessEjbBean/remote");
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
StatelessEjbejb2 =(StatelessEjb)context.lookup("StatelessEjbBean/remote");
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
}
}
最后的運行結果是:
![計算機生成了可選文字:豆prob.ems石JaVodo可亙。些.orotion廈面,o.e不品servers<terminated>StatelessEjbClient[JavaApplication]C:JavaMD叭bin丫avaw.exe(2012234](http://www.vxbq.cn/uploadfile/cj/20141130/20141129100106613.png)
2、有狀態會話Bean
有狀態會話Bean適用于需要若干要求構成才可完成的業務進程。這樣,EJB組件就需要保護方法調用間的狀態變更信息,最形象的就是淘寶購物車的狀態了。在用戶閱讀商品到加入購物車直至購買,我們必須跟蹤用戶的狀態,并且為單個客戶保存狀態信息。
圖1.1是無狀態會話Bean的實例池,EJB容器只需要在實例池中保護若干個Bean實例,便能服務大量的并發的客戶??墒菍τ袪顟B會話Bean來講,這樣是遠遠不夠的。
在有狀態會話Bean中各個Bean實例中存儲的狀態信息僅是單個客戶的。如果和無狀態會話Bean的處理1樣,只是簡單的將實例全部放置實例池中,當大量的并發客戶操作時,內存中運行的有狀態會話Bean實例就會過量而失去控制。
因此,為了限制內存中Bean實例的數量,EJB容器使用了掛起和激活兩個操作。我們先來講說掛起吧。
掛起是甚么呢?就和置之不理1樣的,把它先保存起來,以后再用。在這里就是當有狀態會話Bean實例暫時沒有參與到客戶要求中時,容器就有可能掛起它,它的會話狀態會被安全的保存下來,而且其釋放的內存可以供其他利用(EJB實例)使用。具體的掛起原理以下圖所示:

圖 2.1
這時候候讀者朋友可能會問,那末EJB容器怎樣知道該掛起那個Bean實例呢?上圖中有提到,大部份容器使用最近最少使用的掛起策略,即簡單的掛起最近沒有使用到的有狀態會話Bean實例。
1旦被掛起的有狀態會話Bean實例的客戶再次調用它,被掛起的會話狀態將重新回到有狀態會話Bean實例中。注意我說的是“被掛起的會話狀態”,激活的有狀態會話Bean實例不1定是原來使用的那個有狀態會話Bean實例,也有多是1個新的有狀態會話Bean實例,可是這個新的有狀態會話Bean實例取得的會話狀態正是被掛起的有狀態會話Bean實例的會話狀態。所以我上句話說的是“被掛起的會話狀態”,讀者朋友需要格外注意這點。
具體的激活原理以下圖所示:

圖 2.2
同無狀態會話Bean1樣,我們最后也附上1個有狀態會話Bean的小Demo供大家理解。
首先是EJB的服務器端:
/**
* @ClassName: 有狀態會話Bean Demo實現類
* @Description: EJB
服務器端實現類
* @author 孫麗端
* @date 2014年11月28日20:22:51
*/
package com.tgb.ejb;
public interfaceStatefulEjb {
publicvoid compute(int i);
publicint getResult();
}
/**
* @ClassName: 有狀態會話Bean Demo實現類
* @Description: EJB
服務器端實現類
* @author 孫麗端
* @date 2014年11月28日20:22:51
*/
package com.tgb.ejb;
importjavax.ejb.Remote;
importjavax.ejb.Stateful;
@Stateful
@Remote
public classStatefulEjbBean implements StatefulEjb {
privateint state;
@Override
publicvoid compute(int i) {
state= state +i;
}
@Override
publicint getResult() {
//TODO Auto-generated method stub
returnstate;
}
}
其次是EJB的客戶端調用代碼實現:
/**
* @ClassName: 有狀態會話Bean Demo客戶端類
* @Description: EJB客戶端類
* @author 孫麗端
* @date 2014年11月28日20:22:51
*/
package com.tgb.ejb;
importjavax.naming.InitialContext;
importjavax.naming.NamingException;
public classStatefulEjbClient {
publicstatic void main(String[] args) throws NamingException {
InitialContextcontext = new InitialContext();
StatefulEjbejb1 =(StatefulEjb)context.lookup("StatefulEjbBean/remote");
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
ejb1.compute(1);
System.out.print(ejb1.getResult());
StatefulEjbejb2 =(StatefulEjb)context.lookup("StatefulEjbBean/remote");
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
ejb2.compute(1);
System.out.print(ejb2.getResult());
}
}
最后的運行結果是:
![計算機生成了可選文字:里prob'ems旦,。vodo。且墜吵。,'on曰Conso'e<terminated>StatefuIEjbClient[JavaApplication]C:Java劃D叭blnVavaw.exe(舀012012}一一](http://www.vxbq.cn/uploadfile/cj/20141130/20141129100154411.png)
通過對會話Bean的生命周期和兩個子類型(有狀態會話Bean和無狀態會話Bean)的詳細解說,不知道你明白了1些嗎?
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈