首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

EJB 專家進階指南(四):有狀態會話 Bean 的鈍化與激活機制實戰

     編輯:Java 相關知識

有狀態會話 Bean 的生命週期管理

Stateful Session Bean 為特定客戶維護會話狀態,每個並發用戶對應一個 Bean 實例。為優化記憶體使用,容器在客戶閒置超過閾值時,將 Bean 鈍化 至二級儲存(硬碟),需求恢復時再 激活 回記憶體。此機制依賴 javax.ejb.EnterpriseBean 繼承 java.io.Serializable 介面。

核心回呼方法:ejbPassivate 與 ejbActivate

  • ejbPassivate():容器將 Bean 寫入磁碟前呼叫,開發者應釋放非序列化資源(JDBC 連線、JMS Session、Socket 等),並確保會話狀態欄位可序列化。
  • ejbActivate():容器從磁碟還原 Bean 後呼叫,開發者重新獲取資源、恢復暫態狀態。

容器保證在鈍化/激活週期中,SessionContext、Home 介面、EJBObject 引用、JNDI `java:comp/env` 資源引用自動保持有效,無需手動處理。

完整範例:計數器 Bean 示範鈍化/激活流程

遠端介面

package com.wiley.compBooks.roman.session.count;
import javax.ejb.*;
import java.rmi.RemoteException;

public interface Count extends EJBObject {
    public int count() throws RemoteException; // 遞增計數器
}

Bean 實作類

package com.wiley.compBooks.roman.session.count;
import javax.ejb.*;

public class CountBean implements SessionBean {
    private SessionContext ctx;
    public int val; // 會話狀態:計數器數值

    public int count() {
        System.out.println("count()");
        return ++val;
    }

    public void ejbCreate(int val) throws CreateException {
        this.val = val;
        System.out.println("ejbCreate()");
    }
    public void ejbRemove() { System.out.println("ejbRemove()"); }
    public void ejbActivate() { System.out.println("ejbActivate()"); }
    public void ejbPassivate() { System.out.println("ejbPassivate()"); }
    public void setSessionContext(SessionContext ctx) { this.ctx = ctx; }
}

Home 介面

package com.wiley.compBooks.roman.session.count;
import javax.ejb.*;
import java.rmi.RemoteException;

public interface CountHome extends EJBHome {
    Count create(int val) throws RemoteException, CreateException;
}

客戶端驗證:模擬容器最大實例限制觸發鈍化

部署描述符限制同時最多 2 個 Bean 實例在記憶體中。客戶端建立 3 個 EJB 物件,第 3 個將強制觸發鈍化:

public class CountClient {
    public static void main(String[] args) {
        try {
            Properties props = System.getProperties();
            Context ctx = new InitialContext(props);
            CountHome home = (CountHome) ctx.lookup("CountHome");

            Count[] counts = new Count[3];
            int countVal = 0;
            // 建立 3 個 Bean,第 3 個會被鈍化
            for (int i = 0; i < 3; i++) {
                counts[i] = home.create(countVal);
                countVal = counts[i].count();
                System.out.println(countVal);
                Thread.sleep(500);
            }
            // 再次呼叫,驗證激活邏輯
            System.out.println("Calling count() on Beans...");
            for (int i = 0; i < 3; i++) {
                countVal = counts[i].count();
                System.out.println(countVal);
                Thread.sleep(500);
            }
            // 清理
            for (int i = 0; i < 3; i++) counts[i].remove();
        } catch (Exception e) { e.printStackTrace(); }
    }
}

執行結果分析

伺服端輸出將顯示 ejbPassivate() 與 ejbActivate() 的呼叫順序,證明容器正確管理了 Bean 的持久化與還原。此機制讓有狀態 Bean 在高併發環境下仍能保持良好擴展性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved