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

EJB 2.0 有狀態 SessionBean 完整開發與部署實戰

     編輯:Java 相關知識

雖然 EJB 3 已成為主流,但理解 EJB 2.x 架構對維護舊系統、理解演進歷程仍有價值。本文記錄 EJB 2.0 有狀態 SessionBean 完整開發流程:Bean 類、Component 介面、Home 介面、部署描述檔、JBoss 配置、客戶端呼叫。

一、環境版本

  • JBoss:4.0.2
  • JDK:1.5
  • IDE:IDEA 8.1.4

二、Bean 實作類:HelloStatefulBean

package lavasoft.testejb20yzt;

import javax.ejb.SessionBean;
import javax.ejb.SessionContext;

public class HelloStatefulBean implements SessionBean {
    private SessionContext context;
    private String someOne;

    // 業務方法
    public String sayHello() {
        System.out.println("HelloStatefulBean: sayHello() is called!");
        return "Hello, " + someOne + "!";
    }

    // EJB 2.x 特有:帶參數的 ejbCreate (Stateful 專屬)
    public void ejbCreate(String someOne) {
        System.out.println("HelloStatefulBean: ejbCreate(String) is called!");
        this.someOne = someOne;
    }

    // SessionBean 介面強制實作的生命週期方法 (通常空實作)
    public void ejbActivate() { System.out.println("ejbActivate called"); }
    public void ejbPassivate() { System.out.println("ejbPassivate called"); }
    public void ejbRemove() { System.out.println("ejbRemove called"); }
    public void setSessionContext(SessionContext ctx) {
        System.out.println("setSessionContext called");
        this.context = ctx;
    }
}

關鍵差異:EJB 2.x vs 3.x

三、Component 介面:HelloStateful

package lavasoft.testejb20yzt;

import javax.ejb.EJBObject;
import java.rmi.RemoteException;

public interface HelloStateful extends EJBObject {
    String sayHello() throws RemoteException;  // 必須拋 RemoteException
}

四、Home 介面:HelloStatefulHome

package lavasoft.testejb20yzt;

import javax.ejb.CreateException;
import javax.ejb.EJBHome;
import java.rmi.RemoteException;

public interface HelloStatefulHome extends EJBHome {
    HelloStateful create(String someOne) throws CreateException, RemoteException;
}

Home 介面程式碼 Component 介面程式碼

五、標準部署描述檔:ejb-jar.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC '-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN'
'https://java.sun.com/dtd/ejb-jar_2_0.dtd'>
<ejb-jar>
  <display-name>Hello Stateful EJB</display-name>
  <enterprise-beans>
    <session>
      <display-name>helloStatefulEJB</display-name>
      <ejb-name>helloStatefulEJB</ejb-name>
      <home>lavasoft.testejb20yzt.HelloStatefulHome</home>
      <remote>lavasoft.testejb20yzt.HelloStateful</remote>
      <ejb-class>lavasoft.testejb20yzt.HelloStatefulBean</ejb-class>
      <session-type>Stateful</session-type>
      <transaction-type>Bean</transaction-type>
      <security-identity>
        <use-caller-identity/>
      </security-identity>
    </session>
  </enterprise-beans>
</ejb-jar>

六、JBoss 專屬配置:jboss.xml

<?xml version="1.0" encoding="UTF-8"?>
<jboss>
  <enterprise-beans>
    <session>
      <ejb-name>helloStatefulEJB</ejb-name>
      <jndi-name>ejb/helloStatefulEJB</jndi-name>
    </session>
  </enterprise-beans>
</jboss>

七、客戶端呼叫程式碼

package lavasoft.client;

import lavasoft.testejb20yzt.HelloStateful;
import lavasoft.testejb20yzt.HelloStatefulHome;
import javax.ejb.CreateException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.rmi.PortableRemoteObject;
import java.rmi.RemoteException;
import java.util.Properties;

public class TestStatefulSessionBeanClient {
    public static void main(String[] args) throws Exception {
        Properties props = new Properties();
        props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
        props.setProperty("java.naming.provider.url", "localhost:1099");
        InitialContext ctx = new InitialContext(props);

        // 1. 查詢 Home 介面
        Object objref = ctx.lookup("ejb/helloStatefulEJB");

        // 2. 關鍵:PortableRemoteObject.narrow 進行類型轉換 (RMI-IIOP 要求)
        HelloStatefulHome home = (HelloStatefulHome) PortableRemoteObject.narrow(objref, HelloStatefulHome.class);

        // 3. 透過 Home 建立 Component 介面 (對應 ejbCreate)
        HelloStateful hello = home.create("StatefulEJB");

        // 4. 呼叫業務方法
        String msg = hello.sayHello();
        System.out.println(msg);
    }
}

八、執行結果驗證

客戶端輸出:

Hello, StatefulEJB!

客戶端執行結果

JBoss 控制台輸出:

HelloStatefulBean: setSessionContext() is called!
HelloStatefulBean: ejbCreate(String someOne) is called!
HelloStatefulBean: sayHello() is called!

JBoss 控制台輸出

九、本地介面規則 (補充)

EJB 2.x 本地介面需額外定義:

  • Local Interface:extends EJBLocalObject,方法不拋 RemoteException
  • Local Home:extends EJBLocalHome
  • ejb-jar.xml 使用 <local-home>、<local> 元素
  • JNDI 名稱通常為 ejb/xxxLocal
  • 同 JVM 呼叫無需 PortableRemoteObject.narrow

本地介面規則圖解

十、遷移至 EJB 3 核心步驟

  1. 移除 implements SessionBean、所有 ejbXxx 方法
  2. Component 介面移除 extends EJBObject、RemoteException,加 @Remote
  3. 刪除 Home 介面
  4. Bean 類加 @Stateful,ejbCreate 改為建構子或 @PostConstruct
  5. 刪除 ejb-jar.xml、jboss.xml (或保留僅覆蓋 JNDI)
  6. 客戶端移除 PortableRemoteObject.narrow,直接 ctx.lookup("BeanName/remote") 轉型
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
特性EJB 2.xEJB 3.x
Bean 類implements SessionBeanPOJO + @Stateful/@Stateless
建構方法ejbCreate(...) 由容器呼叫普通建構子 + @PostConstruct
業務介面Component Interface (extends EJBObject)POJO Interface + @Remote/@Local
Home 介面必須 (extends EJBHome)不需要 (JNDI 直接查 Bean)
遠端呼叫RMI-IIOP、PortableRemoteObject.narrowRMI、直接轉型
部署描述檔ejb-jar.xml (強制)註解為主、XML 可選