⑴ EJB有狀態的會話Bean和無狀態的會話Bean的區別
在EJB裡面,會話Bean分為兩種,一種是有狀態的會話Bean,另一種是無狀態的會話Bean,本節主要講解一下兩者之間的區別。
對於有狀態的會話Bean,這種情況屬於,服務端與你單獨開辟了一塊空間與你進行交互。而客戶端感覺服務端單獨為他自己服務似的。而無狀態的會話Bean,則服務端不提供了一個資源但是誰用都行,他不負責。所以客戶端在使用的時候,則會感到這個服務 與其他人共享似的。
服務端
分別創建一個有狀態的會話bean和一個無狀態的會話 Bean。
新建一個EJB項目
新建項目1
新建項目2
然後創建兩個介面,兩個實現。(分別是有狀態和無狀態)
有狀態會話Bean的介面和實現:
public interface StatefulEjb {
public void compute(int i);
public int getResult();
}
@Stateful
@Remote(StatefulEjb.class)
public class StatefulEjbBean implements StatefulEjb {
private int state;
public void compute(int i) {
state += i;
}
public int getResult() {
return state;
}
}
無狀態會話Bean的介面和實現:
public interface StatelessEjb {
public void compute(int i);
public int getResult();
}
@Stateless
@Remote(StatelessEjb.class)
public class StatelessEjbBean implements StatelessEjb{
private int state;
public void compute(int i) {
state += i;
}
public int getResult() {
return state;
}
}
創建完之後的結構如下:
服務端介面
之後部署到JBOSS上,(我用的版本是jboss-5.0.1.GA)然後啟動JBOSS這樣服務端就搭建好了。
客戶端
創建一個Java項目,然後添加一個main方法,這個就不詳細說了。分別測試有狀態的會話Bean和無狀態的會話Bean。
1、創建java項目(略)
2、修改環境,需要添加jar包。(jboss安裝包里根目錄裡面client裡面的所有jar包)
客戶端代碼
//測試有狀態的會話Bean
public class StatefulEjbClient {
public static void main(String[] args) throws NamingException {
//第一次會話
InitialContext context = new InitialContext();
StatefulEjb ejb1= (StatefulEjb) context.lookup("StatefulEjbBean/remote");
System.out.println(ejb1.getResult());
ejb1.compute(1);
System.out.println(ejb1.getResult());
ejb1.compute(1);
System.out.println(ejb1.getResult());
ejb1.compute(1);
System.out.println(ejb1.getResult());
ejb1.compute(1);
System.out.println(ejb1.getResult());
//第二次會話
StatefulEjb ejb2= (StatefulEjb) context.lookup("StatefulEjbBean/remote");
System.out.println(ejb2.getResult());
ejb2.compute(1);
System.out.println(ejb2.getResult());
ejb2.compute(1);
System.out.println(ejb2.getResult());
ejb2.compute(1);
System.out.println(ejb2.getResult());
ejb2.compute(1);
System.out.println(ejb2.getResult());
}
}
測試結果:
有狀態的會話Bean測試結果
//測試無狀態的會話Bean
public class StatelessEjbClient {
public static void main(String[] args) throws NamingException {
//第一次會話
InitialContext context = new InitialContext();
StatelessEjb ejb1= (StatelessEjb) context.lookup("StatelessEjbBean/remote");
System.out.println(ejb1.getResult());
ejb1.compute(1);
System.out.println(ejb1.getResult());
ejb1.compute(1);
System.out.println(ejb1.getResult());
ejb1.compute(1);
System.out.println(ejb1.getResult());
ejb1.compute(1);
System.out.println(ejb1.getResult());
//第二次會話
StatelessEjb ejb2= (StatelessEjb) context.lookup("StatelessEjbBean/remote");
System.out.println(ejb2.getResult());
ejb1.compute(1);
System.out.println(ejb2.getResult());
ejb1.compute(1);
System.out.println(ejb2.getResult());
ejb1.compute(1);
System.out.println(ejb2.getResult());
ejb1.compute(1);
System.out.println(ejb2.getResult());
}
}
測試結果:
無狀態的會話Bean測試結果
對比上述的兩個結果:
有狀態的會話Bean,每一個會話 都是一個新的開始。而無狀態的會話Bean 每個會話用的時候都會接著用上一次的會話。
有狀態會話bean :每個用戶有自己特有的一個實例,在用戶的生存期內,bean保持了用戶的信息,即「有狀態」;一旦用戶滅亡(調用結束或實例結束),bean的生命期也告結束。即每個用戶最初都會得到一個初始的bean。
無狀態會話bean :bean一旦實例化就被加進會話池中,各個用戶都可以共用。即使用戶已經消亡,bean 的生命期也不一定結束,它可能依然存在於會話池中,供其他用戶調用。由於沒有特定的用戶,那麼也就不能保持某一用戶的狀態,所以叫無狀態bean。但無狀態會話bean 並非沒有狀態,如果它有自己的屬性(變數),那麼這些變數就會受到所有調用它的用戶的影響,這是在實際應用中必須注意的。
⑵ 消息驅動的Bean和無狀態的會話Bean有什麼區別
在這里先謝謝了
MDB是通過JMS消息驅動的,當消息隊列中有消息時,將會引發MDB的onMessage方法調用版,而這些JMS消息可能來自於權各種消息生產者,比如POJO、其他消息中間件、EJB等,本實例使用無狀態會話Bean發送JMS消息。
本實例的平台為:netbeans6.7.1 + jdk1.6 + Glassfish2.1 + JSF1.2
實現流程是:通過將jsp頁面表單中輸入的文本消息,發送給JSF後台受管BEAN,受管BEAN再以文本消息作為參數調用會話Bean,會話Bean將文本消息打包成TextMessage發送到消息隊列(消息目的地)當中。消息隊列再驅動MDB對消息進行處理,並列印處理。
⑶ 有狀態會話Bean與無狀態會話Bean的區別
有狀態和無狀態會話bean的本質區別是它們的生命期。
首先解釋一個下面要用到的概專念--用戶:session bean 的用戶實際上就是屬直接調用ejb的類的實例,甚至是這個實例的某個方法。同一個類的不同實例對於session bean 來說是不同的用戶。
有狀態會話bean :每個用戶有自己特有的一個實例,在用戶的生存期內,bean保持了用戶的信息,即「有狀態」;一旦用戶滅亡(調用結束或實例結束),bean的生命期也告結束。即每個用戶最初都會得到一個初始的bean。
無狀態會話bean :bean一旦實例化就被加進會話池中,各個用戶都可以共用。即使用戶已經消亡,bean 的生命期也不一定結束,它可能依然存在於會話池中,供其他用戶調用。由於沒有特定的用戶,那麼也就不能保持某一用戶的狀態,所以叫無狀態bean。但無狀態會話bean 並非沒有狀態,如果它有自己的屬性(變數),那麼這些變數就會受到所有調用它的用戶的影響,這是在實際應用中必須注意的。
⑷ Spring中到底什麼叫有無狀態的Bean,什麼叫
Bean 就是Java類沒有什麼好說的
有無狀態 是說 Java類中如果用戶第一次訪問後改變的狀態
是否可以在將來的多次訪問時繼續可以保持(這個狀態是由Bean自已來維護)
⑸ EJB3 無狀態會話bean代理存根對象 多線程安全嗎
ejbs are thread safe, but stateless session beans are not suitable for storing session/conversational data. since the ejb container (jee server) might choose any instance in the pool to serve client request. that's why it's called "stateless".
if you need to store session/conversational state, ie, you need to save state between multiple pages, you might wanna use the http session object or stateful session bean instead.
⑹ sessionbean可以是有狀態的也可以是無狀態,這個狀態是什麼意思
ejb容器存儲stateless
session
bean,這些bean可能是pre-created的,正由於stateless,每次函數調用容器會認為與上下文無專關所以是動態reassign一個屬bean的實體給客戶端使用,換句話說stateless裡面request的level是per-method
至於debug為什麼是有規律的,可能和jpda的結構和機制有關,我就不太清楚了
初學乍練請多指教
⑺ EJb中有狀態會話構件和無狀態會話構件
時間功能用無狀態會話bean,購物車用有狀態會話bean。(不過現在很多網站類程序都不在EJB端用有狀態會話bean而是在Web端用HTTPsession保存狀態)。
狀態這個詞彙在EJB中是指,我們是否期望伺服器允許這個bean保存有狀態值,因為EJB是啟用了池化特性的,因此一大堆閑置的bean放在池中時它的狀態有沒有必要保存,因為當它下次為另一個用戶的請求服務時這些東西會產生影響結果的可能性。
因此在有狀態會話bean是允許這個EJB實現類有些非靜態的欄位成員,並且在ejbCreate/ejbRemove時會初始化或清理狀態值,另外在我們從客戶端lookup並home.create之後的所有對於這個home.create產生的對象stub1的請求都將在伺服器端也被同一個bean實例處理(因為它可能緩存有上一次請求時留下的狀態值),當然,當我們調用home.create得到另一個客戶端stub2對象時它在伺服器端對應的bean實例可能跟前一次不同但也可以跟你第一次home.create那個stub1是相同的(主要是看你是否已經對第一個stub1調用了remove方法,調用了remove那表示它的生命周期結束,後面的stub2可能依然在伺服器端得到與stub1時相同的實例,因為stub1請求已經完成後伺服器端對應的bean實例回到池中等待重用)。像購物車需要記住車內有什麼物品,這就是」狀態「,在你連續的多次發起添加物品,修改數量和結算請求時需要保持狀態的一致性(我們不能看到別人的購物車的信息)。
ShopHomehome=//...context.lookup(...);
Shopstub1=home.create();
stub1.addProct(proct1);
stub1.addProct(proct2);
stub1.removeProct(proct1);
Shopstub2=home.create();
stub2.addProct(proct1);
stub1.pay();
stub1.remove();
Shopstub3=home.create();
stub3.addProct(proct4);
//在stub1.remove();之後stub3可能在服務端是用stub1當時相同的bean實例來服務的,因為stub1請求已經完成了。但stub2還沒有完成因此stub3和stub2在服務端對應的bean肯定不相同,在stub1.remove()之前stub1和stub2在服務端對應的bean實例也肯定不相同,因此上面這段代碼要求伺服器上的EJB緩沖池中至少有2個ShopEJB的實例,這點伺服器是絕對保證遵守規范的。
對於無狀態會話bean來說,它就是完全不需要照顧這些,它的ejbCreate和ejbRemove這些方法也是完全沒有意義的,不產生任何實際作用,也不需要被伺服器調用的。
技術性的方面,當我們故意在服務端代碼中無條件地拋也一個runtimeexception不處理它,我們在伺服器的exceptionstacktrace中也能看出無狀態和有狀態的區別,因為伺服器對於有狀態會話bean需要記住是哪個連接請求的標記,比如客戶端TCP地址和埠及一個內部唯一性的編號,而對於無狀態會話bean來說,不用區分這些,因此,有些伺服器(比如像WebSphere)為無狀態會話bean提供一個ShareContext的選項,意思就是說既然無狀態那麼應該是線程絕對安全的所以我們不需要多個池化的實例而只需要在伺服器上生成唯一一個實例放入池中就可以了。
⑻ 什麼時候用有狀態session bean,什麼時候用無狀態session bean
1.使用stateless bean,EJB容器能容易的pooling和重用bean,
允許少量的bean去服務很多客戶端。用stateful bean去做同樣
的事情時,bean的狀態在方法調用之間必需要鈍化和活化,可
能導致I/O瓶頸。所以無狀態的一個實際的好處是使用很小的
開銷來容易的pool和重用組件。
2.因為一個stateful session bean在內存中緩沖一個客戶端
的對話,一個bean失敗可能導致失去你的對話。這能導致嚴重
的反響,如果你不在寫bean時考慮到這一點,或者你不使用一
個提供有狀態恢復的EJB產品。在一個無狀態模型裡面,請求
能被透明的重路由到一個不同的組件,因為任何組件都能為
客戶端的需要提供服務。
最大的無狀態的缺點是你需要在每個方法調用中把客戶相關的
的數據推到stateless bean。大多數stateless session bean
將需要接收對一個客戶端特定的一些信息,如對banking bean的
銀行帳戶號碼。這些信息要每次一個客戶端請求到達時被提供到
stateless bean,因為bean不能對一個特定的客戶端保持狀態。
一種向bean提供客戶相關的數據的方法是把數據作為參數傳到
bean的方法中。這可能導致性能下降,然而,只是發生在傳遞的
數據量很大的情況下。這也阻塞了網路,降低了其他進程的帶寬。
另一種為stateless bean提供客戶相關的數據的方法,為那個
bean為一個客戶端持久性的存儲數據。客戶端不需要在一個方法
調用中傳遞所有的狀態,而只簡單的需要從持久化的storage得到
數據。這里的trade-off又是性能:存儲對話持久化的能得到存儲
I/O瓶頸,而不是網路I/O瓶頸。
⑼ weblogic10.3中開發EJB3的無狀態會話Bean的問題
取錯了ejb的jndi 你所看到的這個自動部署的ejb不是你代碼實例的ejb 重啟bea並進入 新的jndi樹應類似如下
⑽ 如何部署無狀態會話bean的部署方法
首先,我們看一復下下面這制張圖片,了解一下通過遠程調用介面的過程,從而知道遠程調用介面和本地調用的區別,從而能夠更好的 根據不同的情況而不同的方式調用EJB。 前面我們已經說了怎麼開發遠程調用的無狀態的會話bean,所以現在我們就講一下本地...