UML软件工程组织

灵活使用EJB的本地和远程接口(三)
作者:Sheldon Wosnick;Viktor Stepanchuk 来 源: 赛迪网
JNDI 绑定和源代码分析

EJB 模块

从 DualEJBModule01 开始。在 EJB Deployment Descriptor 编辑器面板中,选择 Beans 选项卡,然后选择 DualEntity,并且确保 WebSphere Bindings 部分中的 JNDI 名设置为 “ejb/dual/ejb/DualEntityHome” 。保存所有的更改。首先,让我们研究DualEJBModule02 项目中 DualSession EJB 的 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 id="EjbRef_02">
   <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 id="EJBLocalRef_02">
   <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”)是用来控制 DualEntity EJB 的本地接口的使用的。第二个条目(具有名称“doTrace”)准备只用于跟踪。已实现的跟踪功能是相当基本的,但是对于我们的目的来说足够了。 相应的 Java 代码看起来像是下面这样的:

public class DualSessionBean implements javax.ejb.SessionBean {
   private javax.ejb.SessionContext mySessionCtx;
   private boolean doTrace;
   private boolean 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 {
            homeObject = initCtx.lookup("java:comp/env/ejb/DualEntityRemoteHome");
            entityRemoteHome = (DualEntityRemoteHome)
            javax.rmi.PortableRemoteObject.narrow(homeObject,
                  DualEntityRemoteHome.class);
         }
      } catch(NamingException ne){
         // process exception here...
      }
   }
...


在 Java 代码中,EJB 环境变量是作为无状态会话 Bean 对象的生命周期的类变量存储的。DualEntity 的本地接口和 Remote Home Interface 是通过引用访问的;这是首选的方式,并且遵守 EJB 2.0 规范。相对地,ejb-jar.xml 包含描述这些引用的 ejb-ref 和 ejb-local-ref 元素。打开 EJB Deployment Descriptor 编辑器,然后选择 Beans 选项卡。确保 JNDI 名设置为“ejb/dual/ejb/DualSessionHome”。然后转到 References 选项卡,确保对 DualEntity 两个引用指向 JNDI 名“ejb/dual/ejb/DualEntityHome”。必要时可以更改这些值,然后保存所作的更改。

Web 模块

DualWebModule03project 标准的 J2EE Web 部署描述符包含两个重要的代码片段。第一个指定该 Servlet 的初始参数:

...
   <init-param>			
		<param-name>useLocal</param-name>
		<param-value>true</param-value>
   </init-param>
   <init-param>
		<param-name>doTrace</param-name>
		<param-value>true</param-value>
   </init-param>
   <!--
   <init-param>
      <param-name>jndiProviderURL</param-name>
      <param-value>iiop://localhost:2809</param-value>
   </init-param>
   <init-param>
      <param-name>jndiNameOnServer</param-name>
      <param-value>ejb/dual/ejb/DualSessionHome</param-value>
   </init-param>
   <init-param>
      <param-name>initialCtxFactoryClassName</param-name>
      <param-value>com.ibm.ejs.ns.jndi.CNInitialContextFactory</param-value>
   </init-param>
-->
...


上面的代码在意义上类似于前面讨论的 EJB 环境参数。注释掉的 Web 部署描述符部分后面将需要用于分离容器(Separate Containers)拓扑。The Web deployment descriptor section that is commented out will be needed later for the Separate Containers topology. 如果这三个附加的参数没有注释掉,在与此体系结构有关的逻辑将通过该 Servlet 的 init() 方法进行调用。(稍后将对此进行更多的介绍。)第二个代码片段描述了需要用来建立 Servlet 与 EJB 通信的引用:

...
<ejb-ref id="EjbRef_03">
		<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 id="EJBLocalRef_03">
		<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>
...


相对地,DualServlet 的源代码包含该 Servlet 的 init() 方法中的处理逻辑。下面是与处理 EJB 引用有关的代码片段:

...
final String JNDI_NAME_LOCAL = "java:comp/env/ejb/DualSessionLocalHome";
final String JNDI_NAME_REMOTE = "java:comp/env/ejb/DualSessionRemoteHome";
...
   if (useLocal) {
      initCtx = new InitialContext();
      homeObject = initCtx.lookup(JNDI_NAME_LOCAL);
      sessionLocalHome = (DualSessionLocalHome) homeObject;
   } else {
      homeObject = initCtx.lookup(JNDI_NAME_REMOTE);
      sessionRemoteHome =
         (DualSessionRemoteHome) PortableRemoteObject.narrow(
         homeObject,
         DualSessionRemoteHome.class);
   }
...


(下载的源代码中的初始参数处理逻辑实际上更复杂,因为它还处理分离容器(Separate Containers)拓扑。)可以在 DualWebModule03 的 Web Deployment Descriptor 编辑器窗格中,首选选中 DualServlet 的所有设置(包括 Initialization 部分在内),然后转到 References 选项卡,选中 EJB 和 EJB Local 这两个子选项卡。两个引用应该指向 WebSphere Bindings 部分中的JNDI 名“ejb/dual/ejb/DualSessionHome”。

项目依赖性总结

现在我们基本上完成了这些模块,让我们再次回顾一下所有项目(包括 EAR 在内)的依赖性:

·DualJavaModule00 没有依赖性。

·DualEJBModule01 没有依赖性。

·DualEJBModule02 在“Java Build Path”、“Java JAR Dependencies”和“Project References”·设置中必须有 DualJavaModule00、DualEJBModule01 项目。

·DualWebModule03 在“Java Build Path”、“Project References”和“Web Library Projects”设置中必须有 DualJavaModule00、DualEJBModule02 项目。

·DualEARForEJBContainer 在“Project References”设置中必须有 DualJavaModule00、DualEJBModule01、DualEJBModule02;EAR 部署描述符必须有指向 EJB 模块和 Java 模块的引用。

·DualEARForAllInOne 必须有指向所有模块(包括 Java、EJB 和 Web 模块)的引用;EAR 部署描述符同样。

DualEARForWeb 必须有指向 DualJavaModule00、DualEJBModule02、DualWebModule03 模块的项目引用;EAR 部署描述符同样。


版权所有:UML软件工程组织