因爲問題是廣泛的,我會盡量回答不久,並提供鏈接到更多信息。
應用程序容器(在我的情況GlassFish)對EJB施加什麼不同限制取決於它是否是有狀態的?
你的情況主要區別是告訴與以下報價從規格:
無狀態會話bean會話bean,它的實例沒有 會話狀態。這意味着所有bean實例在不涉及爲客戶端調用的方法提供服務時都是 。術語「無狀態」表示對於特定客戶,實例沒有狀態 。但是,實例 的實例變量可以包含跨客戶端調用的方法調用的狀態。這種狀態的例子包括開放的數據庫連接和對企業bean對象的對象引用 。
在@Stateful的情況下,如何從同一個用戶/客戶端一個客戶端的請求被映射到正確的豆(一種從以前要求保持客戶端的狀態)?
在客戶端,您必須存儲對有狀態會話bean的業務接口的引用。你從EJB容器中獲得的這個對象。它是容器創建的對象,包含有關如何定位服務器端對象的詳細信息。有關GlassFish中這些代理的一些信息可以從以下網址找到:
會話Bean何時死亡?在@Stateless完成請求之後,我會立即假定它,但對@Stateful沒有任何線索。
否,無狀態會話bean(SLSB)在請求後不會死亡。無狀態會話bean的壽命爲:
- 它是在容器決定的時候創建的。這在 自然發生在它使用前的某個點上,但在其他情況下,它在 容器的手中。 SLSB創建後,它被放置到池中。
- 當某些客戶端需要調用SLSB中的方法時,在方法調用期間有一個實例從池中被帶走。方法調用完成後,實例 返回到池。然後這個實例(其他人)準備好爲下一個客戶提供服務。
- 新實例由容器創建時JNDI查找或:當容器決定調整池的大小
有狀態會話bean(SFSB)的壽命大致如下
- 生命SLSB的結束注射發生。
- 在其生命週期中,SFSB可以服務多個方法調用。它也可以被鈍化(基本上存儲到光盤以節省資源)並再次激活。
- 當調用remove方法或超時(SFSB未使用一段時間)時,SFSB的壽命結束。容器通常具有實現特定的默認超時時間,並且可以調整超時時間。在Java EE 6(EJB 3.1)中,可以通過StatefulTimeout以每個bean爲基礎調整此超時。
當發生系統異常時,會話bean的附加實例將被丟棄。系統異常是RuntimeException(未標記爲應用程序異常)或java.rmi.RemoteException。事實上,SLSB的實例被丟棄對客戶端來說是透明的。下一次電話肯定會由SLSB的其他實例 服務。對於SFSB,所有未來的業務方法調用都將失敗,因爲SFSB的服務器端實例不再存在。詳細信息可以從EJB 3.1規範第14章中找到。
可以從EJB 3.1規範(4.6,4.7)中找到生命週期的詳細定義。說明比上面更詳細,並有圖表可在Java EE 6 Tutorial。
什麼是對你好的服務設計的主要功效:
@Stateless
public class HelloStateless implements HelloRemote {
@Override
public String getGreeting(String name) {
return "Hi " + name;
}
}
/**
* This design is not possible for Stateless, because
* subsequent calls to setName and getGreeting can be
* handled by two different instances. For stateful it
* is fine, because we use one exclusively one instance.
*/
@Stateful
public class HelloStateful {
private String name;
public void setName(String name) {
this.name = name;
}
public String getGreeting() {
return "Hi " + name;
}
}