EJB 3 透過註解 (`@Stateless`、`@Stateful` 等) 大幅簡化企業級開發,本文系統整理會話 Bean 類型、介面綁定、JNDI 命名、生命週期回調、攔截器、依賴注入與定時服務核心註解用法。
| 註解 | 類型 | 特徵 |
|---|---|---|
| `@Stateless` | 無狀態 | POJO,容器管理實例池,多用戶共享,不保存會話狀態,生命週期超過單次調用 |
| `@Stateful` | 有狀態 | 每用戶專屬實例,維持會話狀態,用戶結束即銷毀,支援鈍化/活化 |
同一 Bean 類可同時標註兩者 (罕見),由客戶端選擇介面決定行為。
預設格式:`耳層名稱/下層名稱` (以 `/` 分隔),預設 JNDI 名 = `Bean名 + 介面類型`
@RemoteBinding(jndiBinding = "com/RemoteHello")
@LocalBinding(jndiBinding = "com/LocalHello")
| 註解 | 觸發時機 | 適用範圍 |
|---|---|---|
| `@PostConstruct` | 實例化後、依賴注入完成 | 有狀態/無狀態 |
| `@PreDestroy` | 容器銷毀實例前 (池移除/過期) | 有狀態/無狀態 |
| `@PrePassivate` | 有狀態 Bean 鈍化前 (閒置超時) | 僅有狀態 |
| `@PostActivate` | 有狀態 Bean 活化後 (恢復狀態) | 僅有狀態 |
| `@Init` | 有狀態 Bean 初始化 (可多個,按建立方式選擇) | 僅有狀態 |
| `@Remove` | 調用標註方法後移除實例 | 僅有狀態 |
順序:`@PostConstruct` → `@Init` → 業務方法 → `@PrePassivate`/`@PreDestroy`
| 註解 | 用途 | 關鍵屬性 |
|---|---|---|
| `@EJB` | 注入 Session Bean 存根 | `beanName` (類名)、`mappedName` (JNDI 名) |
| `@Resource` | 注入任意 JNDI 資源 (DataSource, JMS Queue, Environment Entry) | `mappedName`、`name`、`type`、`authenticationType` |
Setter 注入模式:
@EJB
public void setHelloBean(HelloBeanLocal bean) { this.helloBean = bean; }
容器在屬性首次使用前自動調用 Setter。
所有註解均可被 `ejb-jar.xml` 覆蓋,註解為預設值,XML 為最終配置,支援不修改原始碼調整行為。