全面研读EJB 2.0(1)
EJB 2.0 中引人注目的变化增强了应用程序开发的灵活性和可移植性
Richard Monson-Haefel
OpenEJB 首席设计师
2000 年 6 月
新的 EJB 2.0 规范不仅仅是一个新的阶段性发行版,它加入了许多引人注目的变动,包括 CMP 组件模型中的一些变动和一种新的 bean 类型,它们将增强您在开发应用程序时的灵活性和可移植性。请率先了解此新规范的功能,本月已发布了它的公开草案。
6 月 2 号发布的 Enterprise JavaBeans 2.0 不仅是一个阶段性发行版,而且是该规范的一个新版本。整个规范有 500 多页,比以前的 EJB 1.1 规范长了 200 页 (66%)。该规范中最重要的变动是对容器管理的持久性 (CMP) 所作的更改,以及引入了一种全新的 bean 类型,即 MessageDrivenBean。
EJB 2.0 中的大量更改都集中在一种新 CMP 组件模型的定义中。它完全不同于旧的 CMP 模型,因为它引入了一个全新的成员,即持久性管理器,并引入了全新的方式来定义容器管理的字段,以及定义这些字段与其它 bean 和从属对象的关系。
MessageDrivenBean (消息 bean)的引入也是非常重要的。消息 bean 体现出 JMS (Java Message Service)与 EJB 相集成,以创建出一种全新的 bean 类型,它设计用来处理异步的 JMS 消息。这种振奋人心的新型 bean 为 JMS 客户机提供一种组件模型,允许将它们部署到 EJB 容器系统的丰富而强健的环境中去。
对该规范还作了许多较小的其它更改。这些其它更改虽然也重要,但它们主要是涉及使该规范更严格,以便消除多义性,并使这些组件具有更高的可移植性。本文集中讨论 EJB 2.0 中引入的新 CMP 和消息 bean 组件模型。
我将提供几个具体的例子,所以读者应该很容易跟上并理解它。但是,EJB 初学者可能发现这个材料比较困难,因为它假定读者已对 EJB 有了基本的了解。有关 EJB 的详细信息,请参阅参考资料。
· 容器管理的持久性
容器管理的持久性在 EJB 2.0 中发生了根本变化。在 EJB 2.0 中,持久性管理器在运行时自动处理 CMP 实体 bean 的持久性。持久性管理器负责根据一种称为抽象持久性方案的新的 bean 持久性管理器合约,将实体 bean 映射到数据库。此外,持久性管理器还负责实现和执行多种查找方法,这些查找方法均基于一种称为 EJB QL 的新型查询语言。
注意到以下事实是很重要的,即符合 EJB 2.0 规范的产品必须能支持 EJB 1.1 CMP 模型,又能支持新的 EJB 2.0 模型。虽然这两种模型并不兼容,但是为了保证向后兼容性,就必须能支持 EJB 1.1 模型。
· 抽象持久性方案
为了理解抽象持久性方案是如何工作的,以及它为什么重要,我将为您快速地回顾一下在 EJB 1.1 中是如何处理 CMP 的,随后再讨论在 EJB 2.0 中如何定义它。
· EJB 1.1 中的 CMP 模型
在 EJB 1.1 中,bean 开发人员负责将 bean 类的持久性字段声明为 Java 基本类型或可序列化类型。下列示例显示了一个 Employee 企业级 bean 类,它是按 EJB 1.1 定义的,带有几个 CMP 字段:
// Employee bean 类
public class EmployeeBean implements
java.ejb.EntityBean {
// 实例字段
EntityContext ejbContext;
// 容器管理的字段
public int identity;
public String firstName;
public String lastName;
public double salary;
public Address address;
public Integer ejbCreate(int id, String fname,
String lname){
identity = id;
firstName = fname;
lastName = lname;
return null;
}
...
}
// Address 从属类
public class Address implements Serializable{
public String street;
public String city;
public String state;
public String zip;
}
当将关系数据库用于持久性时,基本字段如 identity、firstName、lastName 和 salary,很容易持久化,因为它们很好地映射为 SQL 类型,如 INTEGER、CHAR 和 DOUBLE。
在 EJB 1.1 中,CMP bean 的 XML 部署描述符提供 cmp-field 元素,用以标识此 bean 类中的持久性字段(容器管理的字段)。如下所示,cmp-field 元素用来区分写入数据库的字段和不写入数据库的字段。例如,ejbContext 字段就不包括在容器管理的字段的列表中,因此它不是持久性字段。
<ejb-jar>
<enterprise-beans>
<entity>
<ejb-name>EmployeeEJB</ejb-name>
...
<persistence-type>Container</persistence-type>
...
<cmp-field><field-name>identity</field-name></cmp-field>
<cmp-field><field-name>firstName</field-name></cmp-field>
<cmp-field><field-name>lastName</field-name></cmp-field>
<cmp-field><field-name>salary</field-name></cmp-field>
<cmp-field><field-name>address</field-name></cmp-field>
...
容器提供者提供一种工具,用来将 bean 的持久性字段映射到数据库表中的列,通常每个 bean 对应一个表。但是,可序列化的类型,如 Address,就比较难于持久化。在 EJB 1.1 中,没有标准的方法将可序列化的对象映射到关系数据库。虽然 Address 类有其自身的字段集,但 XML 部署描述符并没有提供一种机制,来将这些字段映射到数据库。在大多数情况下,人们期望将可序列化的对象(如 Address)作为二进制类型(有时称为 blob 类型)持久化到某个数据库表中。
由于实体 bean 的数据方案逐渐复杂起来,所以这个问题也变得严重了。例如,Employee bean 可能有多个类似于 Address 的子对象,如 Benefits 和 JobPosition。这些子对象称为从属对象,可以形成关系数据库中跨几个表的复杂对象图。另外,EJB 1.1 中的 CMP 在很大程度上不足以持久化与其它 bean 的关系。在 EJB 1.1 中,如果某个 bean 准备维持与另一个 bean 的关系,则容器会自动将主关键字或句柄用作一个链接。与某些其它 bean 的关系其性质可能是双向的,或者要依赖于一些不易用主关键字或句柄来表示的字段,为了保持与这类 bean 的关系,上面的办法已被证明是一种远未完善的机制。
(未完待续)
|