首页 | IT新闻 | 硬件 | 操作系统 | 开发 | 网络编程 | 数据库 | 热门框架 | 网络安全 | 组网 | 建站指南 | 网页制作 | 特效 | 实用技巧 | 服务器 | 办公 | QQ | 探索 | 社区
|
EJB 3.0 的新规范概览及其未来发展
开始 无论如何由于EJB的复杂性使之在J2EE架构中的表现一直不是很好。EJB大概是J2EE架构中唯一一个没有兑现其能够简单开发并提高生产力的组建。 EJB3.0规范正尝试在这方面作出努力以减轻其开发的复杂性。EJB3.0减轻了开发人员进行底层开发的工作量,它取消或最小化了很多(以前这些是必须实现)回调方法的实现,并且降低了实体Bean及O/R映射模型的复杂性。 在本文中,我首先会介绍EJB3.0中几个主要的改变。它对进一步深入了解EJB3.0是非常重要的。随后,我会从更高的层面来描述已经被提交到EJB3.0规范中的细节,并一个个的讲解新的规范中的改变:实体Bean,O/R映射模型,实体关系模型和EJB QL(EJB查询语言)等等。 背景 EJB3.0中两个重要的变更分别是:使用了Java5中的程序注释工具和基于Hibernate的O/R映射模型。 Java5中的元数据工具。 Java5 (以前叫J2SE1.5或Tiger)中加入了一种新的程序注释工具。通过这个工具你可以自定义注释标记,通过这些自定义标记来注释字段、方法、类等等。这些注释并不会影响程序的语义,但是可以通过工具(编译时或运行时)来解释这些标记并产生附加的内容(比如部署描述文件),或者强制某些必须的运行时行为(比如EJB组件的状态特性)。注释的解析可以通过源文件的解析(比如编译器或这IDE工具)或者使用Java5中的APIs反射机制。注释只能被定义在源代码层。由于所有被提交到EJB3.0草案中的注释标记都有一个运行时的RetentionPolicy,因此会增加类文件占用的存储空间,但这却给容器制造商和工具制造商带来了方便。 Hibernate 目前Hibernate非常受欢迎,它是开发源代码的Java O/R映射框架,目的是把开发人员从繁琐的数据持久化编程中解脱出来。它也有一个标准的HQL(Hibernate 查询语言)语言,你可以在新的EJB QL中看到它的影子。Hibernate在处理如数据查询、更新、连接池、事务处理、实体关系处理等方面非常简单。 概览 在已经提交的EJB3.0规范中主要涉及两个方面的改变: 1. 一套以注释为基础的EJB编程模型,再加上EJB2.1中定义的通过部署描述符和几个接口定义的应用程序行为。 2. 新的实体Bean持久化模型,EJBQL也有许多重要的改变。 还有一些有关上述的提议,比如:一个新的客户端编程模型,业务接口的使用以及实体Bean的生命周期。请注意EJB2.1编程模型(包括部署描述符和home/remote接口)仍然是有效的。新的简化模型并没有完全取代EJB2.1模型。 EJB注释 EJB 规范组织一个重要的目标是减轻原始代码的数量,并且他们为此给出了一个完美而简介的办法。在EJB3.0的里,任何类型的企业级Bean只是一个加了适当注释的简单Java对象(POJO)。注释可以用于定义bean的业务接口、O/R映射信息、资源引用信息,效果与在EJB2.1中定义部署描述符和接口是一样的。在EJB3.0中部署描述符不再是必须的了;home接口也没有了,你也不必实现业务接口(容器可以为你完成这些事情)。 比如,你可以使用@Stateless注释标记类把Java类声明为一个无状态回话bean。对于有状态回话bean来说,@Remove注释可以用来标记一个特定的方法,通过这个注释来说明在调用这个方法之后bean的实例将被清除掉。 为了减少描述组件的说明信息,规范组织还采纳了由异常进行配置(configuration-by-exception)的手段,意思是你可以为所有的注释提供一个明确的缺省值,这样多数常规信息就可以据此推断得出。 新的持久化模型 新的实体bean也是一个加了注释的简单Java对象(POJO)。一旦它被EntityManager访问它就成为了一个持久化对象,并且成为了持久化上下文(context)的一部分。一个持久化上下文与一个事务上下文是松耦合的;严格的讲,它隐含的与一个事务会话共存。 实体关系也是通过注释来定义的,O/R映射也是,并提供几种不同的数据库规范操作,在EJB2.1中这些要通过开发人员自己的设计模式或者其它技术来完成的(比如,自增长主键策略)。 深入研究 现在是时候详细了解EJB3.0草案了。让我们开始探讨所有EJB中四种企业级bean,并看看他们在新的规范中是什么样子。 无状态回话bean 在EJB3.0规范中,写一个无状态回话bean(SLSB)只需要一个简单的Java文件并在类层加上@Stateless注释就可以了。这个bean可以扩展javax.ejb.SessionBean接口,但这些不是必须的。 一个SLSB不再需要home接口,没有哪类EJB再需要它了。Bean类可以实现业务接口也可以不实现它。如果没有实现任何业务接口,业务接口会由任意 public的方法产生。如果只有几个业务方法会被暴露在业务接口中,这些方法可以使用@BusinessMethod注释。缺省情况下所有产生的接口都是local(本地)接口,你也可以使用@Remote注释来声明这个接口为remote(远程)接口。 下面的几行代码就可以定义一个HelloWorldbean了。而在EJB2.1中同样的bean至少需要两个接口,一个实现类和几个空的实现方法,再加上部署描述符。
有状态回话bean 除了几个SFSB的特别说明之外,有状态回话bean(SFSB)和SLSB一样精简: ◆一个SFSB应该有一个方法来初始化自己(在EJB2.1中是通过ejbCreate()来实现的)。在EJB3.0的规范中建议这些初始化操作可以通过自定义方法完成,并把他们暴露在业务接口中。在使用这个bean之前由客户端来调用相应的初始化方法。目前规范组织就是否提供一个注释来标记某个方法用于初始化还存在争议。 下面是对以上问题我个人的观点: ◆是否应该有一个注释来标明一个方法进行初始化呢?我的观点是——应该有,这样容器就可以在调用其他方法之前至少调用一个方法来进行初始化。这不仅可以避免不必要的错误(由于没有调用初始化方法)而且可以使容器更明确的判断是否可以重用SFSB实例。我暂且把这个问题放一放,规范组织只考虑为一个方法提供一个注释来声明它是一个初始化方法。 消息驱动Bean 消息驱动Bean是唯一一种必须实现一个业务接口的Bean。这个接口指出bean支持的是哪一种消息系统。对于以JMS为基础的MDB来说,这个接口是 Javax.jms.MessageListener。注意MDB业务接口不是一个真正意义上的业务接口,它只是一个消息接口。 实体Bean ◆实体Bean使用@Entity注释来标记,所有实体bean中的属性/字段不必使用@Transient注释来标记。实体bean的持久化字段可以通过JavaBean-style机制或者声明为public/protected字段来实现。 实体关联 EJB3.0同时支持Bean之间双向的合单向的关联,它们可以是一对一、一对多、多对一或者是多对多的关联。然而双向关联的两端还要分为自身端(owning side)和对方端(inverse side)不同的端。自身端负责向数据库通告关联的变更。对于多对多的关联自身端必须明确的声明。实际上对方端通过isInverse=true进行注释(由此自身端就不必说明了而是由另一段推断出)。看来上面的描述,规范组织还能说让EJB变的简单了吗? O/R映射 EJB3.0 中的O/R映射模型也有了重要的改变,它从原来的abstract-persistence-schema-based变成了现在的Hibernate- inspired模式。尽管目前规范组织还在就此进行讨论但是一个明确的模型将会出现在下一个版本的草案中。 举例来说,O/R映射模型将通过bean类中的注释来声明。而且此方法还会指出对应的具体表和字段。O/R映射模型提供了一套自有的SQL;而且除了提供一些基本的SQL外还支持某些高层开发的功能。比如,有一个通过@Column注释声明的字段columnDefinition,那么可以写这样的SQL: columnDefinition="BLOB NOT NULL" 客户端程序模型 一个EJB客户端可以通过 @Inject注释以一种“注入”的方式获得一个bean的业务接口引用。你也可以使用另一个注释 @javax.ejb.EJBContext.lookup()来完成上面的操作,但是规范中没有告诉我们一个普通的Java客户端怎样获得一个Bean 的实例,因为这个普通的Java客户端是运行在一个客户端容器中,它无法访问@javax.ejb.EJBContex对象。现在还有另外一种机制来完成上面的工作那就是使用一个超级上下文环境对象:@javax.ejb.Context()。但是规范中没有指出该如何在客户端中使用这个对象。 EJB QL EJB QL可以通过@NamedQuery来注释。这个注释有两个成员属性分别是name和queryString.一旦定义了这些属性,就可以通过 EntityManager.createNamedQuery(name)来指向这个查询。你也可以创建一个标准的JDBC风格的查询并使用 EntityManager.createQuery(ejbqlString)或 EntityManager.createNativeQuery (nativeSqlString)(这个方法用于执行一个本地查询)来执行查询。 EJB QL有两个地方可以定义其参数。javax.ejb.Query接口提供了定义参数、指向查询、更新数据等等方法。下面是一个EJBQL指向查询的例子:
下面列出了一些EJB QL的增强特性: ◆支持批量更新和删除。
◆支持group by 和having。 在提交的EJB3.0草案中,EJB QL与标准SQL非常的接近。实际上规范中甚至直接支持本地的SQL(就像我们上面提到的那样)。这一点对某些程序员来说也许有些不是很清楚,我们将在下面进行更详细的讲解。
多样性 方法许可(Method permissions)可以通过@MethodPermissions或@Unchecked注释来声明;同样的,事务属性也可以通过 @TransactionAttribute注释来声明。规范中仍然保留资源引用和资源环境引用。这些一样可以通过注释来声明,但是有一些细微的差别。比如,上下文(context)环境要通过注入工具控制。容器根据bean对外部环境引用自动初始化一个适当的已经声明的实例变量。比如,你可以象下面这样获得一个数据源(DataSource):
在上面的例子中如果你不指定引用资源的名称(name)那么其中的customerDB会被认为是默认值。当所有的引用属性都可得到时,@Injec注释就可以这样写:
容器负责在运行时初始化customerDB数据源实例。部署人员必须在此之前在容器中定义好这些资源属性。 更好的消息是:那些以前必须检测的异常将一去不复返。你可以声明任意的应用程序异常,而不必在再抛出或捕获其他类似CreateException和 FinderException这样的异常。容器会抛出封装在javax.ejb.EJBException中的系统级异常或者只在必要时候抛出 IllegalArgumentException或IllegalStateException异常。 EJB文件处理模式 在我们结束本节之前,让我的快速的浏览一下容器提供商在EJB处理模式方面可能的变更。规范中对此并没有明确的表态,但我可以想到至少两种模式。 ◆一种办法是首先利用EJB文件生成类似于EJB2.1部署模式的文件(包括必要的接口和部署描述符)然后再用类似于EJB2.1的方式来部署这个EJB组件。当然,这样产生的部署描述符可能并不标准但是它可以解决同一个容器对EJB2.1和EJB3.0兼容的问题。 你有什么想法? EJB3.0规范的制定正在有序的进行,为了使 EJB的开发变得更加容易,EJB规范组织作出的努力是有目共睹的。就像他们说的那样,一切对会变得简单,但做到这一点并不容易。目前已经定义了50个注释标记(还有几个将在下一个草案中发布),每一个都有自己的缺省规则和其他的操作。当然,我真的不希望EJB3.0变成EJB2.1的一个翻版"EJB 3.0 = EJB 2.1 for dummies"(希望这个等式不要成立)。最后,我还是忍不住要提一些我自己的观点: ◆首先,规范确实使反复部署变得容易了,并且有一个简单的模式来访问运行时环境。我还是觉得home接口应该放弃。 在本次提交的草案中,一个实体bean只是一个数据库的映射。并且是基于非抽象持久化模式和简单的数据访问模式的更加简单开发。 ◆我对模型变更持保留态度,我认为在EJB中包含SQL脚本片断并不是个好注意。一些开发人员完全反对包含某些“SQL片段(SQLness)”(比如 @Table 和 @Column注释)。我的观点是这些SQLness是好的,据此我们可以清楚的知道我们到底要数据库作些什么。但是某些SQL段我看来并不是很好,比如columnDefinition="BLOB NOT NULL",这使得EJB代码和SQL之间的耦合太过紧密了。 与其他规范的关联 目前可能影响到EJB3.0的JSR有JSR175(java语言元数据工具)和JSR181(Java Web服务元数据)JSR175已经初步完成并且不会和EJB3.0有太大的冲突;但是JSR181与EJB3.0有两个关联的地方: ◆Web Service接口:EJB规范将采用一种机制适应JSR181以便可以把一个bean实现为一个Web service并告诉Web service如何被客户端调用。 在J2EE 1.5中的一些开发规范可能与EJB3.0有关联。除了上面说到的几个关联之外现在没有其他的开发规范与EJB3.0有冲突。 结束语 在使EJB的开发变得简单高效之前,我们还有很长一段路要走。规范组织在降低EJB的开发难度方面起了个好头。O/R映射模型的提议还处在早期阶段,规范组织正在完善它。我希望它不要太复杂也不要与SQL过分的耦合。让我们不要只是停留在期望、希望、思考和请求中:提出你的想法并把你的建议发送给规范组织ejb3-feedback@sun.com。JCP并不是很民主的组织,但是你的建议一定是有价值的。 相关链接
频道热门
热门新闻
|
精粹集锦
特别推荐
频道精选
|