kapok

垃圾桶,嘿嘿,我藏的这么深你们还能找到啊,真牛!

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  455 随笔 :: 0 文章 :: 76 评论 :: 0 Trackbacks

http://dev2dev.bea.com.cn/techdoc/webser/200406201.html
开发实体EJB 增强的性能和开发
摘要
Enterprise JavaBean (EJB)
是一些应用程序组件,它们实现了 EJB 体系结构规范,并且是 Java 2 Enterprise Edition (J2EE) 平台的一部分。EJB 是开发和部署分布式的、可伸缩的、事务型的、安全的、可移植的、基于组件的商业应用的理想选择。

Enterprise JavaBean (EJB)一些应用程序组件,它们实现了EJB体系结构规范,并且是Java 2 Enterprise Edition (J2EE) 平台的一部分。EJB是开发和部署分布式的、可伸缩的、事务型的、安全的、可移植的、基于组件的商业应用的理想选择。

基于EJB的商业应用需要一个EJB容器,用于运行时的执行。所有遵从J2EE规范的应用服务器,包括WebLogic 8.1在内,都提供了EJB容器。

EJB体系结构背后的主要动机是关系的分离:它将与应用程序基础设施相关的部分(例如事务处理和安全性)与核心应用程序部分(例如业务逻辑)分离开来。简言之,EJB体系结构通过指定EJB容器与EJB开发者之间职责的区别,从而达到这种关系上的分离。例如,透明地实现事务处理是EJB容器的职责,而实现业务逻辑则应由EJB开发者负责。虽然EJB容器执行任务时可能需要某些线索(hint),但是,比起实际地实现这些与基础设施相关的活动来,提供这类线索(通过基于XML的部署描述符)的代价是非常少的。总之,这种关系分离的策略使得商业应用的开发比其他方式要高效得多。

EJB体系结构规范有4种版本:1.01.12.02.1。事实上,EJB version 1.0已经过时了,而最新版本,即2.1,由于刚刚才出现,所以还没有广泛提供。BEA WebLogic Server 8.1同时支持1.12.0这两种版本。我们强烈建议在WebLogic Server 8.1中进行开发时使用EJB version 2.0

实体bean是一种EJB。除了EJB背后的一般动机外,使用实体bean的特定动机是为持久存储中的业务域(business-domain)实体提供一种驻留在内存中的、可共享的、面向对象的视图。通常,业务域对象就是关系数据库中一个表里面的一行。在本文中,我们讨论了关于在WebLogic Server 8.1环境下Entity EJB的设计、开发和部署的特定问题。至于关于EJB技术的综合教程,我们推荐http://java.sun.com/j2ee上的J2EE教程。

概述
实体bean是设计用来管理关系数据库中的数据的。在BEA WebLogic Server 8.1环境下,Entity EJB的开发包括EJB的设计、生成、打包和部署。

从设计的角度来看,实体bean可以由两条正交轴线来分类:持久性和访问。顺着持久性这条轴线,有两种类型的实体beanBean管理的持久性(Bean-managed persistenceBMP)和容器管理的持久性(Container-managed persistenceCMP)。如果是CMP,则EJB容器将管理实体bean的持久性。而对于BMP,则由实体bean的开发者通过指定的Java代码来管理实体bean的持久性。CMPBMP之间的选择是互斥的。顺着访问这条轴线,又有两种类型的bean:远程的和本地的。远程实体bean提供了定位的透明性,并且可以从不同的Java虚拟机上访问。相反,本地实体bean只能在同一应用服务器内访问。本地和远程之间的选择不是互斥的,因此可以设计具有双重接口的bean

EJB体系结构规范中,每个实体EJB组件都是由一组指定的Java类和一组指定的XML部署描述符组成。EJB的打包过程包括将所有指定的EJB Java类文件和XML部署描述符文件打包到一个Java Archive (JAR)文件中。如果实体EJB还要依赖于一些Java助手类文件,那么也可以将这样的类文件包括到EJB JAR文件中,或者将它们单独打包到一个不同的JAR文件中。

EJB的部署可分为两种方式,要么是在BEA WebLogic Server 8.1内直接部署EJB JAR文件以及所依赖的任何JAR文件,要么是首先将EJB jar文件和所有依赖的JAR文件打包到一个企业应用归档(enterprise application archiveEAR)文件内,然后再在WebLogic Server 8.1内部署这个EAR文件。

设计EJB
在设计一个实体时,需要考虑的几个重要选择是:

  1. 是设计一个CMP实体bean还是一个BMP实体bean
  2. 是设计一个本地实体bean,还是设计一个远程实体bean,抑或是设计一个双重接口的实体bean
  3. 是设计一个粗粒度(coarse-grained)的实体bean,还是一个细粒度(fine-grained)的实体bean
  4. 是使用数据传输对象,还是使用getset方法来访问实体EJB中的数据。

下面将讨论在开发实体EJB时要面临的这些设计选择。

CMPBMP
记住,虽然可能存在一些很合理的例外,但是一般情况下我们强烈推荐使用CMP这种设计。至于为什么要选择CMP,而不是BMP,这里有三大主要原因。

  1. BMP相比,CMP提供了跨多种不同数据库的可移植性,因为CMP实体bean不包含任何特定于数据库的持久性代码。CMP易于设计、实现和维护。
  2. 通常,CMP拥有好于BMP的性能,因为EJB容器将自动生成特定于数据库的代码,并且这些代码将为目标数据库而优化。
  3. CMP通过使用本地接口,使得在相关EJB的网络中程序性地(programmatically)进行导航变得非常容易。

本地接口、远程接口和双重接口
因为CMP通过本地接口管理着实体EJB之间的关系,所以我们强烈建议总是提供一个本地接口。我们认为远程接口需要的时候很少,但是如果仔细评估一下就会证明远程接口也是需要的。所以,我们还是设计一个双重接口吧。

本地接口通过本地客户机提供了对EJB的优化的访问;远程方法调用(remote method invocationRMI)的语义不要求通过本地客户机、使用本地接口来访问EJB

远程客户机与EJB容器位于不同的虚拟机上,它需要RMI和远程接口来访问EJB。从理论上讲,单单设计一个本地实体存在着一个明显的缺点,那就是只有在相同应用服务器内的客户机才能访问该实体bean。然而,这只是一个理论上的缺点,因为实际上很少需要从应用服务器之外访问实体EJB

粗粒度与细粒度
这是一个非常有争议的专题,所以还应根据您个人的经验小心地评价关于此专题的一些不同观点。我们的选择是,实体EJB最常用于表示应用程序业务域中各个实体,所以应该让实体EJB尽量地细粒度,不过也应将设计限定为仅提供一个本地接口。关于这个问题的争论始于EJB体系结构规范1.x版本,当时只能通过一个远程接口来访问实体EJB。建立在EJB 1.x版本基础上的任何反对使用细粒度实体EJB的观点,虽然当时也有合理之处,但是在EJB体系结构规范2.0  中却已不合时宜了,并且最终遭到反对。请谨记:有些专家可能不同意我们的观点,所以我们鼓励您通过实验进行考证,并在此专题上形成自己的观点。

数据传输对象与GetSet方法
这又是一个有争议的专题。我们的观点如下所述:

  • 在实体EJB的本地接口中暴露CMP持久字段的所有get访问器(accessor)方法。
  • 为不属于实体EJB主键的一部分的每个CMP持久字段创建包装器(wrapperset方法,并且在实体EJB的本地接口中暴露这些包装器方法。使用这些包装器方法背后的动机是,CMP要求所有持久字段都具有抽象方法setXXX,如果需要在这些setXXX方法内进行任何验证,那么就可以先在包装器方法内完成验证,然后再调用相应的setXXX方法。如果不需要这样的验证,那么省掉包装器方法而直接包括setXXX方法也无不可。
  • 在某些少见的环境下,可能要求实体EJB有一个远程接口,这时可以为每个实体EJB定义一个数据传输对象,将该数据传输对象作为实体EJB的远程接口中的一个参数,暴露其getset方法。

生成和打包EJB
EJB体系结构规范中,每个实体EJB组件都由一组指定的Java类和一组指定的XML部署描述符组成:

  1. 一个必需的实现实体bean核心功能的bean类。
  2. 一个远程接口、本地接口或双重接口,该接口为实体bean提供了适当的客户机视图。
  3. 一个远程主接口(home interface)、本地主接口或者双重主接口,该接口为实体bean的生命周期管理提供了适当的接口。
  4. 如果是具有组合主键的实体bean,那么还有一个必需的主键类。
  5. 一个ejb-jar XML部署描述符文件,EJB体系结构规范version 2.0对此作了规定。
  6. 一个特定于供应商的 weblogic-ejb-jar XML部署描述符文件,BEA WebLogic Server 8.1 对此有规定。
  7. 如果是CMP实体bean,那么还应有一个特定于供应商的weblogic-cmp-rdbms-jar XML 部署描述符文件,BEA WebLogic Server 8.1对此有规定。

这里使用的例子实体EJB是一个CMP实体EJB,它有一个远程接口,它的名称是AccountEJB。在随WebLogic Server 8.1一起安装的示例文件中,即 /weblogic81/samples/server/examples/src/examples/ejb20/basic/containerManaged目录下,可以找到这个实体EJB

实体bean EJB类和接口可以用EJBGen工具来生成。

EJBGen
EJBGen
是一种EJB 2.0代码生成器,它能够从一个EJB bean类生成本地接口/远程接口、本地主接口/远程主接口、主键类和部署描述符。在EJB bean类中使用EJBGen标记来指定不同的EJB设计配置(例如,本地/远程和CMP/BMP)。在WebLogic Server 8.1 SP01 中,EJBGen 类被包括在/weblogic81/server/lib/weblogic.jar中。在WebLogic Server 8.1 SP02 & SP03中,EJBGen类被包括在/weblogic81/server/lib/ejbgen.jar文件中。将ejbgen.jar添加到Classpath中,以便使用EJBGen工具。

EJBGen通过以下命令来调用:

javadoc -docletpath ejbgen.jar -doclet weblogic.tools.ejbgen.EJBGen
<EjbBeanClass>.java

该命令有一些选项:

  • -d [directory]: 创建EJB/接口和部署描述符时所在的目录。
  • -descriptorDir [directory]: 创建部署描述符时所在的目录。
  • -wls7: 有了–wls7这个选项,就会生成WebLogic Serve 7.1部署描述符。

如果要将更早版本的BEA WebLogic Server部署描述符转换成WebLogic Server 8.1部署描述符,那么可以使用DDConverter

DDConverter
DDConverter
是一个命令行工具,用于将更早版本的XML部署描述符(ejb-jar.xmlweblogic-ejb-jar.xmlweblogic-cmp-rdbms-jar.xml)转换成当前版本的WebLogic Server DDConverter可以用以下命令来调用:

java weblogic.ejb20.utils.DDConverter [options] –d destDir file1 [file2...]

在这个命令中,file是指包含EJB 1.1部署描述符的一个EJB 1.0部署描述符文件或JAR文件。DDConverter的一部分选项有:

  • -d destDir:部署描述符输出到的目录。
  • -EJBVer output EJB version: 指定输出EJB版本。缺省版本是2.0

在部署EJB之前,必须将其打包到一个JAR文件或EAR文件中。

EJB JAR文件
EJB JAR
文件的结构由EJB类和接口以及包含部署描述符的 META-INF目录组成。创建一个目录source/ejb20/basic/containerManaged和一个目录source/ejb20/basic/containerManaged/META-INF。将Account.javaAccountBean.javaAccountHome.java ProcessingErrorException.java/weblogic81/samples/server/examples/src/examples/ejb20/basic/containerManaged目录复制到source/ejb20/basic/containerManaged目录。将ejb-jar.xmlweblogic-ejb-jar.xmlweblogic-cmp-rdbms-jar.xml/weblogic81/samples/server/examples/src/examples/ejb20/basic/containerManaged目录复制到source/ejb20/basic/containerManaged/META-INT目录。

通过Apache Ant使用编译好的EJB Java类文件和部署描述符创建一个JAR文件,Apache Ant  是一种基于Java的联编(build)工具。Apache Ant工具需要一个联编文件。创建一个带有目标的build.xml文件(参见清单1),以便编译EJB源文件并利用编译好的类文件生成一个JAR 文件。

build.xml文件复制到/source目录。运行build.xml中的ejb-jar目标。EJB JAR文件生成在source/dist目录中。EJB JAR可以使用BEA WebLogic appc编译器来编译。用appc编译器来编译并不是必需的,但这是BEA WebLogic推荐的。

appc
appc
编译器利用EJB JAR文件生成容器类,并验证部署描述符。在部署EJB JAR文件之前用 appc编译EJB JAR类的好处是,这样可以识别出在部署EJB JAR时可能发生的错误。要运行 appc编译器,应保证weblogic.jar被包括在Classpath中。appc可以通过以下命令来调用:

java weblogic.appc [options] <jar file or directory>

appc有一些选项:

  • -output<file>:指定输出目录。
  • -keepgenerated: 保留生成的.java文件。
  • -compiler<java>: Java编译器设置成可用。

部署EJB
要部署一个实体EJBJAR文件,必须有一个带有Java命名和目录接口(Java Naming and Directory InterfaceJNDI)名称的数据源。在我以前的文章(WLDJ, Vol. 3, issue 1)中我已解释了如何创建连接池(Connection Pool)。用JNDI "examples-dataSource-demoPool" 创建一个Tx Datasource。这个JNDI 名应该与weblogic-cmp-rdbms-jar.xml部署描述符文件的 <data-source-name>元素中指定的名称相一致。

为了部署实体EJB JAR文件,在管理控制台(administration console)中选择Deployments>EJB Modules节点。单击Deploy a new EJB Module链接(见图1)。

这时会显示出Deploy an EJB Module窗体(见图2)。在Deploy an EJB Module 窗体中选择 upload your files(s) 链接。接着将会显示一个Upload and Install an Application or Module 窗体。选择一个要上载的EJB JAR文件,并单击Upload按钮。

这时会显示出Deploy an EJB Module窗体。选择myserver链接。接着可以看到myserver目录中的子目录列表。单击upload directory链接。在upload目录中选择要部署的EJB JAR,并单击Target Module按钮(见图3)。这时会显示一个Select Targets for this EJB module窗体(见图4)。

Select targets for this EJB module窗体中选择一个或多个目标服务器,并单击Continue按钮。在接着显示出的窗体中,在Name字段中指定用于要部署的EJB模块的名称(见图5)。

单击Deploy按钮以部署EJB JAR文件。这样一来,EJB JAR将被部署到服务器上,并且有一个EJB节点被添加到EJB Modules节点中(见图6)。

EJB应用程序还可以部署到BEA WebLogic Server上,方法是将EJB JAR文件复制到该应用程序要部署到的那个域上的applications目录中。

BEA WebLogic为在 WebLogic服务器上部署EJB提供了一些建议。

  1. 应该将EJB作为企业归档应用程序(EAR应用程序)中的一个EJB JAR来部署,以利于应用程序的移植和修改。
  2. 引用了其他EJBEJB应该部署在相同的应用程序中;weblogic-ejb-jar.xml中的enable-call-by-reference元素应该设置成True,以获得更好的性能。
  3. 部署在WebLogic服务器群集上的EJB应该其次地(homogeneously)部署到群集内每一台受管的服务器上。如果一个EJB只需部署到群集内的一台服务器上,那么在部署之前应使用appc编译器先对 EJB进行编译。

结束语
EJB
应用程序的开发包括创建EJB类、编译EJB类和利用编译好的EJB类创建一个JAR文件,以及将EJBJAR部署到BEA WebLogic Server。通过遵循关于设计、生成和部署EJB JARBEA WebLogic Server上的一些建议,EJB应用程序的性能得到了提高。

参考资料

l           Programming WebLogic Enterprise JavaBeans: http://edocs.bea.com/wls/docs8.1/ejb/index.html

关于作者

Deepak Vohra 是一名 Web 开发人员,同时也是一名 NuBean 顾问。

Ajay Vohra Compuware 公司的一名高级软件工程师。

Listing 1:  build.xml file
<project name="example-entity-ejb" default="all" basedir=".">
  <property name="source" value="."/>
   <property name="ejb" value="ejb20/basic/containrManaged"/>
  <property name="build" value="{source}/build"/>
   <property name="j2sdkee" value="c:/j2sdkee1.3.1"/>
  <property name="dist" value="{source}/dist"/>
 
  <target name="init">
    <!-- Create the time stamp -->
    <tstamp/>
    <mkdir dir="{build}"/>
    <mkdir dir="{build}/META-INF"/>
    <mkdir dir="{dist}"/>
  </target>
  <target name="ejb">
    <javac srcdir="{source}" classpath="{j2sdkee}/lib/j2ee.jar"
               destdir="{build}" includes="{ejb}/*.java"/>
    <copy  todir="{build}/META-INF">
    <fileset   dir="META-INF" includes="*.xml" />
    </copy>
  </target>
  <target name="ejb-jar" depends="ejb">
    <jar jarfile="{dist}/entityejb.jar" includes="META-INF/*.xml,
               {ejb}/*.class" basedir="{build}"/>
  </target>
</project>
posted on 2005-07-13 00:58 笨笨 阅读(319) 评论(0)  编辑  收藏 所属分类: J2EEALL

只有注册用户登录后才能发表评论。


网站导航: