什麼是 Session Bean?
Session Bean 在 J2EE 伺服器上代表一個客戶端,封裝商務任務,屏蔽伺服器端複雜性。特性:
- 非共享:僅服務單一客戶端
- 互動式:類似交談會話
- 非持久:客戶端結束會話即銷毀
開發三大核心檔案
- Bean 類別 (如 `CartEJB.java`):實作 `SessionBean` 介面
- Home 介面 (如 `CartHome.java`):繼承 `EJBHome`,定義 `create()`
- Remote 介面 (如 `Cart.java`):繼承 `EJBObject`,定義商務方法
輔助類別:例外類別 (`BookException`)、驗證工具 (`IdVerifier`),打包於同一 EJB-JAR 中。
Bean 類別規範 (以 CartEJB 為例)
public class CartEJB implements SessionBean {
String customerName, customerId;
Vector contents;
// 多載 ejbCreate 初始化狀態
public void ejbCreate(String person) throws CreateException { ... }
public void ejbCreate(String person, String id) throws CreateException { ... }
// 商務方法
public void addBook(String title) { contents.addElement(title); }
public void removeBook(String title) throws BookException { ... }
public Vector getContents() { return contents; }
// 生命週期回呼 (容器管理,通常為空實作)
public CartEJB() {}
public void ejbRemove() {}
public void ejbActivate() {}
public void ejbPassivate() {}
public void setSessionContext(SessionContext sc) {}
}
關鍵規則
- 實作 `SessionBean`、public 類別、非 abstract/final
- 至少一個 `ejbCreate`、回傳 void、參數為合法 RMI 類型
- 無參建構子、無 `finalize()`
- 商務方法:public、非 static/final、名稱不衝突 EJB 保留字、拋出 `RemoteException` + 應用例外
- 系統級錯誤拋出 `EJBException` (容器包裝為 `RemoteException` 給客戶端)
Home 介面與 Remote 介面契約
| 介面 | 繼承自 | 核心定義 | 關鍵規則 |
| Home | EJBHome | `create(...)` 對應 `ejbCreate` | 拋出 `RemoteException` + `CreateException`、回傳 Remote 介面 |
| Remote | EJBObject | 商務方法簽章 | 每方法對應 Bean 實作、參數/回傳合法 RMI 類型、必拋 `RemoteException` |
狀態管理模式選擇
Stateful Session Bean (有狀態)
- 擁有實例變數保存會話狀態 (如 `customerName`、`contents`)
- 狀態隨會話存續,`remove()` 或逾時後銷毀
- 適用:需初始化狀態、保留客戶端互動資訊、互動式應用
Stateless Session Bean (無狀態)
- 不保存客戶端專屬狀態,實例變數僅在方法呼叫期間有效
- 所有實例等價,容器可任意分配給任意客戶端
- 效能較高:無鈍化/活化開銷,支援更多並發客戶端
- Home 必須有無參 `create()`,Bean 有無參 `ejbCreate()`
- 適用:無客戶端親和性任務 (查詢、驗證、工具方法)
生命週期詳解
Stateful
- 客戶端呼叫 `create()` → 容器實例化 → `setSessionContext()` → `ejbCreate()` → 就緒階段
- 就緒階段:容器可依 LRU 演算法鈍化 (`ejbPassivate()`) 至二級快取
- 鈍化期間客戶端呼叫 → 容器活化 (`ejbActivate()`) 回就緒
- 客戶端呼叫 `remove()` → 容器 `ejbRemove()` → 實例待 GC 回收
Stateless
僅兩階段:不存在 ↔ 就緒 (方法呼叫期間)。從不鈍化。
開發建議總結
- 優先考慮 Stateless 以獲取擴展性與效能,除非確需會話狀態。
- 商務邏輯集中於 Bean,介面僅定義契約。
- 例外處理:應用例外 (如 `BookException`) 直接傳遞;系統例外包裝為 `EJBException`。
- 輔助類別隨 EJB-JAR 部署,確保版本一致性。