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

Session Bean 進階教學 (三):無狀態 Session Bean 完整實作與生命週期

     編輯:Java 相關知識

無狀態 vs 有狀態 Session Bean

特性有狀態 (Stateful)無狀態 (Stateless)
客戶狀態維護會話狀態 (欄位值)不維護客戶特定狀態
create 方法可多個、可帶參數僅一個、無參數
執行個體共用專屬單一客戶容器池化,多客戶共用
Passivate/Activate頻繁發生較少見 (池化機制)
適用場景購物車、精靈式流程查詢服務、工具方法、批次處理

無狀態 Bean 介面設計

Remote:StatelessHello.java


package usingj2ee.hello;
import java.rmi.*;
import javax.ejb.*;

public interface StatelessHello extends EJBObject {
    String greet(String thingToGreet) throws RemoteException;
}

單一業務方法,參數傳入,直接回傳結果,無狀態依賴。

Home:StatelessHelloHome.java


package usingj2ee.hello;
import java.rmi.*;
import javax.ejb.*;

public interface StatelessHelloHome extends EJBHome {
    StatelessHello create() throws RemoteException, CreateException;
}

唯一無參 create(),符合無狀態規範。

實作類別:StatelessHelloImpl.java


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 + "!";
    }
}

生命週期方法深度解析

setSessionContext(SessionContext)

  • Bean 建立後立即呼叫,僅一次
  • 取得 SessionContext 參考,後續可用於:

// 取得 Remote 介面參考 (傳遞給其他 Bean)
context.getEJBObject()

// 取得 Home 介面參考
context.getEJBHome()

// 交易管理 (僅 BMT)
context.getUserTransaction()

// 安全性檢查
context.isCallerInRole("admin")
context.getCallerPrincipal()

ejbCreate()

  • 客戶呼叫 Home create() 觸發
  • 無狀態 Bean:所有實例共用同邏輯,通常無初始化碼
  • 有狀態 Bean:依參數初始化會話狀態

ejbPassivate() / ejbActivate()

  • Passivate:容器將閒置 Bean 從記憶體移至次級儲存 (序列化),必須釋放不可序列化資源 (JDBC 連線、Socket、JMS Connection)
  • Activate:客戶再次呼叫,容器還原 Bean,**重新取得資源**
  • 無狀態 Bean 池化機制下較少觸發,但仍需正確實作

ejbRemove()

  • 客戶呼叫 remove() 或容器逾時淘汰觸發
  • 最終清理:關閉連線、釋放資源、移除註冊的監聽器

部署配置差異

在 deploytool 中:

  • Bean 類型選擇 Stateless Session Bean
  • 或確認 未勾選 "Manages Conversational State"

客戶端測試:TestStatelessHello.java


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!

SessionContext 進階用法:傳遞 Bean 參考

錯誤做法:otherBean.doSomething(this); — this 是實作類別,非 Remote 介面。

正確做法:


otherBean.doSomething((MyRemote) sessionContext.getEJBObject());

最佳實踐:在 setSessionContext 儲存 context,提供 getSessionContext() 供內部方法使用。

結語

無狀態 Session Bean 是高擴展性企業應用的核心:無會話狀態 = 容器可自由池化 = 輕鬆支撐高併發。掌握其生命週期管理 (特別是 Passivate/Activate 中的資源釋放/重取)、正確使用 SessionContext 取得 Remote 參考、部署時正確標記 Stateless,是開發高效能 EJB 系統的關鍵。

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