| 特性 | 有狀態 (Stateful) | 無狀態 (Stateless) |
|---|---|---|
| 客戶狀態 | 維護會話狀態 (欄位值) | 不維護客戶特定狀態 |
| create 方法 | 可多個、可帶參數 | 僅一個、無參數 |
| 執行個體共用 | 專屬單一客戶 | 容器池化,多客戶共用 |
| Passivate/Activate | 頻繁發生 | 較少見 (池化機制) |
| 適用場景 | 購物車、精靈式流程 | 查詢服務、工具方法、批次處理 |
package usingj2ee.hello;
import java.rmi.*;
import javax.ejb.*;
public interface StatelessHello extends EJBObject {
String greet(String thingToGreet) throws RemoteException;
}
單一業務方法,參數傳入,直接回傳結果,無狀態依賴。
package usingj2ee.hello;
import java.rmi.*;
import javax.ejb.*;
public interface StatelessHelloHome extends EJBHome {
StatelessHello create() throws RemoteException, CreateException;
}
唯一無參 create(),符合無狀態規範。
package usingj2ee.hello;
import java.rmi.*;
import java.util.*;
import javax.ejb.*;
public class StatelessHelloImpl implements SessionBean {
private SessionContext context;
public StatelessHelloImpl() {}
public void setSessionContext(SessionContext aContext) {
context = aContext;
}
public void ejbCreate() throws CreateException {
// 無狀態 Bean 通常無初始化需求
}
public void ejbActivate() {
// 從池中取出時呼叫,可重新取得資源
}
public void ejbPassivate() {
// 歸還池中時呼叫,釋放資源 (連線等)
}
public void ejbRemove() {
// 銷毀時清理
}
// 業務方法:純函數式,無副作用
public String greet(String thingToGreet) {
return "Hello " + thingToGreet + "!";
}
}
SessionContext 參考,後續可用於:
// 取得 Remote 介面參考 (傳遞給其他 Bean)
context.getEJBObject()
// 取得 Home 介面參考
context.getEJBHome()
// 交易管理 (僅 BMT)
context.getUserTransaction()
// 安全性檢查
context.isCallerInRole("admin")
context.getCallerPrincipal()
create() 觸發remove() 或容器逾時淘汰觸發在 deploytool 中:
package usingj2ee.hello;
import java.util.*;
import javax.naming.*;
import javax.rmi.*;
public class TestStatelessHello {
public static void main(String[] args) {
try {
Context ctx = new InitialContext();
StatelessHelloHome home = (StatelessHelloHome) PortableRemoteObject.narrow(
ctx.lookup("StatelessHello"), StatelessHelloHome.class);
StatelessHello bean = (StatelessHello) home.create();
System.out.println(bean.greet("World"));
System.out.println(bean.greet("Solar System"));
System.out.println(bean.greet("Universe"));
bean.remove();
} catch (Exception e) { e.printStackTrace(); }
}
}
輸出:
Hello World!
Hello Solar System!
Hello Universe!
錯誤做法:otherBean.doSomething(this); — this 是實作類別,非 Remote 介面。
正確做法:
otherBean.doSomething((MyRemote) sessionContext.getEJBObject());
最佳實踐:在 setSessionContext 儲存 context,提供 getSessionContext() 供內部方法使用。
無狀態 Session Bean 是高擴展性企業應用的核心:無會話狀態 = 容器可自由池化 = 輕鬆支撐高併發。掌握其生命週期管理 (特別是 Passivate/Activate 中的資源釋放/重取)、正確使用 SessionContext 取得 Remote 參考、部署時正確標記 Stateless,是開發高效能 EJB 系統的關鍵。