- 热门文章:
- · HTTP会话对象 VS 有状态EJB
- · WLS 6.0测试中的JNDI 和Web应用
- · WebLogic Server 环境下先进的JMS设计模式
- · 项目推出:针对WLS 7和8.1的COMMONJ WORK MANAGER
- · JMS集群第1部分
- · WebLogic平台的Web SSO(SAML)解决方案
- · WebLogic8中的扩展JSP标签实例解析
- · 解决打开文件过多的问题
- · 使用JMS在集群应用程序中分配任务
- · WebLogic Workshop 8.1 Jav…
- · BEA Workshop8.1之Java Pag…
- · WebLogic Server8.1新功能介…
使用 EJBGen:"一个对三个"
EJBGen 简介
本文中我们将介绍用于生成兼容WebLogic Server 6.1 EJB的工具,即EJBGen,它是由BEA WebLogic架构师Cedric Beust 开发的(http://www.beust.com/cedric/ejbgen)。它可以很容易地添加到你的 WebLogic上的应用中,且是IDE无关的 —— 仅需要在bean类中添加一些Javadoc标签。令人遗憾的是,此工具是不开放源代码的,因为它是由Cedric单独开发的,但是只要您加入邮件列表,就可以与他联系。无论是发出请求还是发现bug,Credric都会在短期内对这些进行处理。如果您需要开放源代码解决方案,则可以使用XDoclet (http://sourceforge.net/projects/xdoclet),它是从JBoss创始人Rickard Oberg所写的EJBDoclet发展而来的。
在本文中,我创建了一组WebLogic Server 6.1上可部署的EJB,表示简单的Order系统。其中有两个实体bean,代表一个订单及它的相关项。将使用EJB 2.0 CMP关系,允许我们从订单EJB对这些项进行访问。我们还有一个会话bean,它操作这些实体bean以便完成工作。
使用EJBGen
EJBGen允许您将EJB信息放在Javadoc标签中,这些标签嵌入在bean类中。特殊标签格式如下:
| /** * @ejbgen:tagname attribute = value attribute2 = value2 ... */ |
根据标签类型的不同,这些@ejbgen标签或者放在类级别,或者放在方法级别。在类级别,您可以声明EJB的名称、JNDI名称和实体bean的属性。方法级别属性标记给定方法的信息。最常使用的标签是组成Remote或Local接口的方法所使用的标签(使用@ejbgen:remote-method或@ejbgen:local-method)。
| /** * @ejbgen:remote-method */ public String viewMaxOrders() { |
创建了bean类并且在源码中插入了Javadoc标签之后,可以通过Javadoc客户端运行EJBGen了:
| % javadoc -docletpath /path/to/ejbgen.jar -doclet EJBGen YourEJBs.java |
还有命令行选项可以对EJBGen生成文件的方式进行调整。其中许多选项都使您可以更改不同元素的前缀和后缀。
要生成名为FooRemote.java而不是Foo.java的远程接口,运行以下命令(注意 –remoteSuffix):
| % javadoc -docletpath ejbgen.jar -doclet EJBGen -remoteSuffix Remote FooEJB.java |
EJBGen站点提供了所有命令行选项的文档。
EJBGen 功能
EJBGen 还有以下功能:
· 包含EJB 2.0 全部功能(本地接口/CMP关系/消息驱动bean)
· 生成在WebLogic Server 6+ 上可部署的代码和部署描述符
· 可以生成实体Bean的值对象
· 属性文件:可以在bean类内定义和使用属性。通过{ property name }方式使用属性
· 支持Javadoc标签继承。基本适配器类可以设置标准值,然后实际的bean继承行为以及方法
· 生成ANT构建文件
如果生成ANT构建文件,运行EJBGen后,可以运行
| % ant -buildfile ejbgen-build.xml |
可以按如下所示调整变量:
· ant.buildFileName:buildfile的名称
· ant.projectName:项目的名称
· ant.docletPath:ejbgen.jar的路径
创建使用Javadoc标签的会话bean。现在我们看一个实际的例子,先是操作实体bean的会话bean。OrderViewerEJB.java将具有以下方法:
· viewMaxOrders():返回最大数量的订单,其将是,以显示我们在类级别javadoc注释中对它们的设置 。
· viewOrders():返回系统中的订单。
· addOrder(orderId, orderBy, orderName):插入订单条目 。
· addOrderItem(orderID, itemID, itemName, amount):这将为所给订单插入一项 。
· deleteOrders():删除所有订单及其中的项 。
类级别定义
在类级别,我们需要定义这是一个会话bean的事实,其相关信息为:JNDI名称;EJB对实体bean的本地引用;和环境entries。
标签:@ejbgen:session
此处仅需要的属性是将bean的名称告诉EJBGen。我们还定义自由内存池中最大数量的bean(WebLogic缓存信息),及默认事务属性将是“Required”。
| /** * OrderViewer Bean views orders: * * @ejbgen:session * ejb-name = OrderViewer * max-beans-in-free-pool = 100 * default-transaction = Required * * ... other tags ... */ public class OrderViewerEJB implements SessionBean { |
表1中显示了ejbgen:session标签的所有属性。
标签:@ejbgen:jndi-name
这个标签非常重要;它不仅定义JNDI名称,而且EJBGen也通过这个标签知道是否生成远程接口、本地接口,还是这两个接口都生成或都不生成!因为我们想将会话bean公开给远程客户端,所以我们将使用远程属性:
| /** * OrderViewer Bean views orders: * * ... other tags ... * * @ejbgen:jndi-name * remote = ejbgenexamples.OrderViewer * * ... other tags ... */ public class OrderViewerEJB implements SessionBean { |
对于本地接口,我们将添加属性“local = local-jndi-name”。
标签:@ejbgen:ejb-local-ref
我们的OrderViewer将使用实体bean说明订单和订单项。EJB 2.0引进了“本地接口”概念,它强迫组件在本地VM中“谈话”,而不越过远程边界。当使用实体bean时,最佳实践是在本地将会话bean(可以远程的)与实体bean一起使用。我们将分别定义对两个实体bean的本地引用(清单1)。
|
清单1 /** * OrderViewer Bean views orders: * * ... other tags ... * * @ejbgen:ejb-local-ref * home = ejbgenexamples.OrderLocalHome * local = ejbgenexamples.OrderLocal * jndi-name = ejbgenexamples.OrderLocalHome * name = ejb/OrderHome * type = Entity * * @ejbgen:ejb-local-ref * home = ejbgenexamples.OrderItemLocalHome * local = ejbgenexamples.OrderItemLocal * jndi-name = ejbgenexamples.OrderItemLocalHome * name = ejb/OrderItemHome * type = Entity * * ... other tags ... */ public class OrderViewerEJB implements SessionBean { |
使用这些本地引用,我们可以通过查询“java: comp/env/ <name>”来查询OrderLocal Home,从而获得对Home接口的访问权:
| OrderLocalHome orderHome = (OrderLocalHome) new InitialContext().lookup("java:/comp/env/ejb/Order-Home"); |
要使用远程接口引用EJB,使用@ejbgen:ejb-ref标签。
标签:@ejbgen:env-entry
要定义环境entries,使用ejbgen:env-entry标签。我们将定义环境条目保持最大数量订单的整数值:
| /** * OrderViewer Bean views orders: * * ... other tags ... * * @ejbgen:env-entry * name = maxOrders * type = java.lang.Integer * value = 10 * * ... other tags ... */ public class OrderViewerEJB implements SessionBean { |
注意,类型必须给完整的(比如是java. lang.Integer,而不是Integer)。
方法级别定义
我们想对远程客户端将可以使用的所有方法进行标记。或者,您还可以使用方法的事务属性的值(即覆盖我们在类级别定义的默认值)和单独的级别。这里我们标记addOrder()方法:
| /** * Add an order * * @ejbgen:remote-method */ public void addOrder(Integer id, String orderBy, String name) |
我们将看到实体bean将标记它们的方法@ejbgen:local-method。现在我们就完成了会话bean的创建!
创建OrderItem实体Bean
使用实体bean与使用会话bean相似。其中包括几个不同的类级别标签;我们将标签容器应该管理的字段及主键。将生成OrderItem实体,其包括三个字段 – itemid、itemname和itemamount – 这些字段将是持久的。
数据库表还将包含ORDER_ID,这是Order实体中的外键(稍后讨论)。现在我们将忽略OrderItem将与Order有关系这个事实。
类级别定义
在类级别,我们将定义实体定义、JNDI名称和实体finder签名,并且创建数据库中的表。
标签:@ejbgen:entity
像会话bean一样,我们需要定义实体bean的名称,可以定义诸如默认事务值等属性。我们还需要定义数据库中表的名称、主键类别和要使用的数据源:
| /** * @ejbgen:entity * ejb-name = OrderItemEJB * data-source-name = orderPool * table-name = OrderItems * prim-key-class = java.lang.Integer * default-transaction = Required * * ... other tags ... */ public abstract class OrderItemEJB implements EntityBean { |
表2中显示了ejbgen:entity标签的所有属性。
标签:@ejbgen:jndi-name
这个标签与会话相同,但是因为我们使用实体,所以将仅创建本地接口:
| /** * ... other tags ... * * @ejbgen:jndi-name * local = ejbgenexamples.OrderItemLocalHome * * ... other tags ... |
标签:@ejbgen:finder
每个finder方法都必须有一个ejbgen:finder标签。您必须指定方法签名,包括您可能要抛出的任何例外。而且,还要给出您希望使用的EJB Query Language语句。我们将定义findItemsByName()方法,它检索具有所给名称的每一项:
| /** * @ejbgen:finder * signature = "Collection findItemsByName(String name)" * ejb-ql = "WHERE name = ?1" |
标签:@ejbgen: create-default-dbms-tables
如果进行开发,可以使WebLogic创建数据库表:
| * @ejbgen:create-default-dbms-tables |
方法级别定义
所有抽象的get()方法都必须标记为容器管理的持久字段,我们提供列名映射。必须标记为主键,而且如果要想能够从组件接口调用这些方法,我们还必须对接口进行标记(远程或本地)。下面是OrderItem的主键:
| /** * @ejbgen:cmp-field column = id * @ejbgen:local-method * @ejbgen:primkey-field */ public abstract Integer getId(); public abstract void setId(Integer id); |
创建Order实体bean并将其与OrderItem相关联
WebLogic Server 6.1 支持EJB 2.0关系,其他许多J2EE服务器没有这个功能。然而,WebLogic Server6.1没有部署描述符工具来部署CMP关系实体(XML必须手动操作),所以我们将使用EJBGen的功能来完成此项工作。
我们将有一个一对多的关系,在这个关系中一个订单可以有多个关联项。在订单EJB中,我们能够通过getItems()获得订单的集合,从集合中我们可以通过OrderLocal getOrder()返回订单。像定义这些抽象的方法,我们需要在每一类中配置ejbgen:relation标签(Order-EJB和OrderItemEJB)。创建这个关系的步骤如下所示:
1. OrderItem:配置ejbgen:relation标签
2. OrderItem:创建容器管理的关系
3. Order:配置ejbgen:relation标签
4. Order:创建容器管理的关系
OrderItem:配置 ejbgen:
relation 标签
此项是关系中“多”的一方。关系双方共享同一名称,target-ejb是要使用此关系的bean的名称。因为我们有target-ejb属性,您可以将所有关系标签放入一个EJB bean类中。因为多重属性,我们将告诉EJBGen这些相关的外键列和映射到容器管理的关系的字段。删除订单时,我们希望相关的订单项能自动删除,这样就有了cascade-delete选项的需求:
| * @ejbgen:relation * multiplicity = many * name = OrderCanHaveMultipleItems * target-ejb = OrderItemEJB * fk-column = order_id * cmr-field = order * cascade-delete = True |
OrderItem:创建容器管理的关系
我们可以从订单EJB中的订单对象得到此订单。标记CMR字段并将其声明为本地方法:
| /** * @ejbgen:cmr-field * @ejbgen:local-method */ public abstract OrderLocal getOrder(); public abstract void setOrder(OrderLocal order); |
Order:配置ejbgen:relation标签
此Order是关系中“一”的一方。此关系必须有相同的关系名称:
| * @ejbgen:relation * multiplicity = one * name = OrderCanHaveMultipleItems * target-ejb = OrderEJB |
Order:创建容器管理的关系
因为一个订单有许多返回值,我们使用OrderItems的集合:
| /** * @ejbgen:cmr-field * @ejbgen:local-method */ public abstract Collection getItems(); public abstract void setItems(Collection items); |
如果您曾经使用过CMP关系,您可能已经多少感到厌烦了。然而通过EJBGen创建CMP关系相当容易。我从来不想手动构建关系的XML。我想使用GUI构建关系,或者可以使用EJBGen。要想进一步使用EJBGen,可以使用能够构建EJBGen可识别类的GUI。请查看免费软件Middlegen (http://boss.bekk.no/boss/middlegen/)。
部署系统
现在我们有三个Java源文件:OrderEJB.java、OrderItemEJB.java和OrderViewerEJB.java。从这些文件我们将使用EJBGen生成接口和XML部署描述符。下面的build脚本将打包一个ejb-jar文件:
| javadoc -docletpath c:\ejbgen\ejbgen.jar -doclet EJBGen ejbgenexamples\Order*EJB.java cd ejbgenexamples javac -classpath %CLASSPATH%;.. *.java cd .. mv *.xml META-INF jar cvf c:\bea\wlserver6.1\config\ mydomain\applications\ejbgen.jar * |
在运行应用程序前,我们必须先在应用服务器(WebLogic Server)上配置数据源,注意既“orderPool”。清单2显示了客户端的main()方法,其添加、查看、然后删除订单。
|
清单 2 public static void main(String[] args) throws Exception { Context ic = getInitialContext(); OrderViewerHome home = (OrderViewerHome) ic.lookup("ejbgenexamples.OrderViewer"); OrderViewer v = home.create(); System.out.println("Add Order"); v.addOrder(new Integer(1), "Dion", "Books"); v.addOrderItem(new Integer(1), new Integer(1), "EJB v3", 36.55f); v.addOrderItem(new Integer(1), new Integer(2), "Mastering EJB", 45.95f); System.out.println("The Max Orders: " + v.viewMaxOrders()); System.out.println("Display Orders:\n" + v.viewOrders() ); System.out.println("Delete Orders"); v.deleteOrders(); } |
结束语
我们了解了使用EJBGen为WebLogic Server 6.1开发EJB的方法。此工具使我们可以每个EJB的生成仅使用一个文件来完成,而不需要开发三个Java文件和多个相关的部署描述符。它是一个非常简洁的预处理系统 —— 甚至还有可以生成EJBGen可识别代码的其他工具!
- · 总结:第一个Java控件
- · 教程:构建第一个Java控件
- · 用WebLogic Workshop开发EJB
- · 用WebLogic Workshop调试应…
- · WLS 9.1与MQ v5.3 通过JMS Bridge通信配置
- · 在Apache Xindice中保存XML文档
- · 升级到WebLogic 9的十大理由
- · 在JAVA EE环境下使用Kodo EJB
- · Weblogic Server 9新特性:J2EE Libraries 和 Optional Packages
- · WebLogic Server 9新特性:JSR-181 Web Services
- · WebLogic Server 9.0:JMS增强功能
- · WebLogic Server9.0产品重点新特性介绍
- · 在Spring中实现事务挂起
- · ALUI 界面深入客户化——替换Portal内置组件
- · ALUI在解决企业门户上的优势
- · AquaLogic User Interaction开发入门
- · 添加协作服务
- · 使用WebLogic SIP Server和WebLogic Workshop驱动Cantata媒体服务器
- · 深入Beehive标签库系列教程 - 前提条件
- · 深入Beehive标签库系列教程(1) - 基本NETUI标签
- · 深入Beehive标签库系列教程(3) - 表单标签:单选框
- · 深入Beehive标签库系列教程(5) - 表单控件:下拉框
- · 深入Beehive标签库系列教程(6) - 使用标签遍历数据
- · 赢得网络服务开发人员的三大…
- · 大规模的财政应用和面向服务…
- · BEA实现了新的Web服务标准
- · 赢得Web服务开发者青睐的“…
- · 第11步:运行Request Quote…
- · 第10步:将报价从工作流发给…
- · 第9步:将报价写入文件系统
- · 第8步:创建报价文档
- · 第7步:设计并行执行路径
- · 第5步:创建一个Perform节点
- · RFID基础知识
- · RFID应用趋势分析
- · 如何实现与沃尔玛等巨头进行RFID对接
- · RFID项目常见问题分析
- · RFID应用架构规划指南
