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

靈活運用 EJB 本地與遠端介面 (三):JNDI 綁定配置與原始碼深度解析

     編輯:Java 相關知識

本篇深入剖析雙介面 EJB 專案的 JNDI 綁定配置細節、部署描述符關鍵片段與核心 Java 實現邏輯,揭示 useLocal 環境變數如何動態控制介面路由,以及 Servlet 與 Session Bean 如何透過 JNDI 查找建立通訊鏈路。

一、 EJB 模組配置詳解

1. DualEJBModule01 (實體 Bean 模組)

  • EJB 部署描述符編輯器 → Beans 分頁 → 選擇 DualEntity。
  • WebSphere Bindings 區:JNDI 名稱設為 ejb/dual/ejb/DualEntityHome。

2. DualEJBModule02 (會話 Bean 模組) - ejb-jar.xml 關鍵片段

<env-entry>
    <env-entry-name>useLocal</env-entry-name>
    <env-entry-type>java.lang.Boolean</env-entry-type>
    <env-entry-value>true</env-entry-value>
</env-entry>
<env-entry>
    <env-entry-name>doTrace</env-entry-name>
    <env-entry-type>java.lang.Boolean</env-entry-type>
    <env-entry-value>false</env-entry-value>
</env-entry>

<ejb-ref>           <!-- 遠端介面引用 -->
    <ejb-ref-name>ejb/DualEntityRemoteHome</ejb-ref-name>
    <ejb-ref-type>Entity</ejb-ref-type>
    <home>dual.ejb.DualEntityRemoteHome</home>
    <remote>dual.ejb.DualEntityRemote</remote>
    <ejb-link>DualEJBModule01.jar#DualEntity</ejb-link>
</ejb-ref>

<ejb-local-ref>     <!-- 本地介面引用 -->
    <ejb-ref-name>ejb/DualEntityLocalHome</ejb-ref-name>
    <ejb-ref-type>Entity</ejb-ref-type>
    <local-home>dual.ejb.DualEntityLocalHome</local-home>
    <local>dual.ejb.DualEntityLocal</local>
    <ejb-link>DualEJBModule01.jar#DualEntity</ejb-link>
</ejb-local-ref>

關鍵點:

  • useLocal 控制介面選擇;doTrace 控制除錯輸出。
  • 同時聲明 ejb-ref (遠端) 與 ejb-local-ref (本地),透過 ejb-link 關聯同一實體 Bean。

3. DualSessionBean 核心實現邏輯 (setSessionContext)

public class DualSessionBean implements javax.ejb.SessionBean {
    private javax.ejb.SessionContext mySessionCtx;
    private boolean doTrace, useLocal;
    private DualEntityRemoteHome entityRemoteHome;
    private DualEntityLocalHome entityLocalHome;

    public void setSessionContext(javax.ejb.SessionContext ctx) {
        mySessionCtx = ctx;
        try {
            Context initCtx = new InitialContext();
            Boolean option = null;

            // 讀取環境變數
            option = (Boolean) initCtx.lookup("java:comp/env/useLocal");
            useLocal = option.booleanValue();
            option = (Boolean) initCtx.lookup("java:comp/env/doTrace");
            doTrace = option.booleanValue();

            if (doTrace)
                System.out.println("DualSessionBean#setSessionContext: useLocal=" + useLocal);

            Object homeObject = null;
            if (useLocal) {
                // 本地介面:直接窄化
                homeObject = initCtx.lookup("java:comp/env/ejb/DualEntityLocalHome");
                entityLocalHome = (DualEntityLocalHome) homeObject;
            } else {
                // 遠端介面:需 PortableRemoteObject.narrow
                homeObject = initCtx.lookup("java:comp/env/ejb/DualEntityRemoteHome");
                entityRemoteHome = (DualEntityRemoteHome)
                    javax.rmi.PortableRemoteObject.narrow(homeObject, DualEntityRemoteHome.class);
            }
        } catch (NamingException ne) { /* 異常處理 */ }
    }
    // ... 業務方法根據 useLocal 委派給 entityLocalHome 或 entityRemoteHome
}

設計精華:

  • 環境變數作為無狀態 Session Bean 實例變數快取,生命週期同 Bean。
  • 本地介面直接強制轉型;遠端介面必須經 PortableRemoteObject.narrow (RMI-IIOP 規範要求)。
  • 符合 EJB 2.0 規範的引用聲明與查找模式。

4. DualSession Bean 綁定配置

  • Beans 分頁:JNDI 名稱 = ejb/dual/ejb/DualSessionHome。
  • References 分頁:對 DualEntity 的兩個引用 (遠端/本地) 皆指向 JNDI ejb/dual/ejb/DualEntityHome。

二、 Web 模組配置詳解

1. web.xml - Servlet 初始化參數

<context-param>
    <param-name>useLocal</param-name>
    <param-value>true</param-value>
</context-param>
<context-param>
    <param-name>doTrace</param-name>
    <param-value>true</param-value>
</context-param>
<!-- 分離容器架構需用的參數,此處註解掉 -->
<!--
<context-param>
    <param-name>ejbHost</param-name>
    <param-value>localhost</param-value>
</context-param>
<context-param>
    <param-name>ejbPort</param-name>
    <param-value>2809</param-value>
</context-param>
<context-param>
    <param-name>useLocal</param-name>
    <param-value>false</param-value>
</context-param>
-->

2. web.xml - EJB 引用聲明

<ejb-ref>           <!-- 遠端會話 Bean 引用 -->
    <ejb-ref-name>ejb/DualSessionRemoteHome</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <home>dual.ejb.DualSessionRemoteHome</home>
    <remote>dual.ejb.DualSessionRemote</remote>
    <ejb-link>DualEJBModule02.jar#DualSession</ejb-link>
</ejb-ref>

<ejb-local-ref>     <!-- 本地會話 Bean 引用 -->
    <ejb-ref-name>ejb/DualSessionLocalHome</ejb-ref-name>
    <ejb-ref-type>Session</ejb-ref-type>
    <local-home>dual.ejb.DualSessionLocalHome</local-home>
    <local>dual.ejb.DualSessionLocal</local>
    <ejb-link>DualEJBModule02.jar#DualSession</ejb-link>
</ejb-local-ref>

3. DualServlet 核心邏輯 (init 方法)

public class DualServlet extends HttpServlet {
    private static final String JNDI_NAME_LOCAL  = "java:comp/env/ejb/DualSessionLocalHome";
    private static final String JNDI_NAME_REMOTE = "java:comp/env/ejb/DualSessionRemoteHome";

    private boolean useLocal, doTrace;
    private DualSessionLocalHome sessionLocalHome;
    private DualSessionRemoteHome sessionRemoteHome;

    public void init() throws ServletException {
        super.init();
        // 讀取 context-param
        ServletContext ctx = getServletContext();
        useLocal = Boolean.valueOf(ctx.getInitParameter("useLocal")).booleanValue();
        doTrace  = Boolean.valueOf(ctx.getInitParameter("doTrace")).booleanValue();

        try {
            Context initCtx = new InitialContext();
            Object homeObject = null;
            if (useLocal) {
                homeObject = initCtx.lookup(JNDI_NAME_LOCAL);
                sessionLocalHome = (DualSessionLocalHome) homeObject;
            } else {
                homeObject = initCtx.lookup(JNDI_NAME_REMOTE);
                sessionRemoteHome = (DualSessionRemoteHome)
                    PortableRemoteObject.narrow(homeObject, DualSessionRemoteHome.class);
            }
        } catch (NamingException ne) { throw new ServletException(ne); }
    }

    // doGet/doPost 中根據 useLocal 呼叫 sessionLocalHome 或 sessionRemoteHome.create()
}

註:下載原始碼中包含分離容器拓撲的額外參數處理邏輯 (ejbHost/ejbPort),此處簡化。

4. Web 模組綁定配置

  • Web Deployment Descriptor 編輯器 → DualServlet 設置 → References 分頁。
  • EJB 子分頁 (遠端引用) 與 EJB Local 子分頁 (本地引用) 皆指向 WebSphere Bindings JNDI:ejb/dual/ejb/DualSessionHome。

三、 專案依賴關係總覽

專案依賴專案 (Java Build Path / Project References / Web Library Projects)
DualJavaModule00無
DualEJBModule01無
DualEJBModule02DualJavaModule00、DualEJBModule01
DualWebModule03DualJavaModule00、DualEJBModule02
DualEARForEJBContainerDualJavaModule00、DualEJBModule01、DualEJBModule02 (EAR 描述符引用 EJB/JAVA 模組)
DualEARForAllInOne所有模組

正確配置依賴後,編譯錯誤應自動消失。

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