有状态回话bean
除了几个sfsb的特别说明之外,有状态回话bean(sfsb)和slsb一样精简:
·一个sfsb应该有一个方法来初始化自己(在ejb2.1中是通过ejbcreate()来实现的)。在ejb3.0的规范中建议这些初始化操作可以通过自定义方法完成,并把他们暴露在业务接口中。在使用这个bean之前由客户端来调用相应的初始化方法。目前规范组织就是否提供一个注释来标记某个方法用于初始化还存在争议。
·bean的提供者可以用@remove注释来标记任何sfsb的方法,以说明这个方法被调用之后bean的实例将被移除。同样,规范组织仍然在讨论是否要有一种机制来处理这种特殊的情况,即当这个方法出现异常的情况下bean的实例是否被移除。
下面是对以上问题我个人的观点:
·是否应该有一个注释来标明一个方法进行初始化呢?我的观点是——应该有,这样容器就可以在调用其他方法之前至少调用一个方法来进行初始化。这不仅可以避免不必要的错误(由于没有调用初始化方法)而且可以使容器更明确的判断是否可以重用sfsb实例。我暂且把这个问题放一放,规范组织只考虑为一个方法提供一个注释来声明它是一个初始化方法。
·对于第二个问题我的观点也是肯定的。这有利于bean的提供者合客户端程序对其进行控制。只有一个遗留的问题:那就是一旦调用这个方法失败,是否能移除这个bean 的实例?答案是不能,但是它将会在回话结束的时候被移除。
消息驱动bean
消息驱动bean是唯一一种必须实现一个业务接口的bean。这个接口指出bean支持的是哪一种消息系统。对于以jms为基础的mdb来说,这个接口是 javax.jms.messagelistener。注意mdb业务接口不是一个真正意义上的业务接口,它只是一个消息接口。
实体bean
·实体bean使用@entity注释来标记,所有实体bean中的属性/字段不必使用@transient注释来标记。实体bean的持久化字段可以通过javabean-style机制或者声明为public/protected字段来实现。
·实体bean可以使用助手类来描述其状态,但是这些类的实例并没有持久化唯一性(persistent identity)的特性(即,唯一标识这个bean的字段等),实际上这些助手类与他们的实体bean实例是紧密结合的;并且这些对象还是以非共享方式来访问实体对象的。
实体关联
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文件处理模式
在我们结束本节之前,让我的快速的浏览一下容器提供商在ejb处理模式方面可能的变更。规范中对此并没有明确的表态,但我可以想到至少两种模式。
·一种办法是首先利用ejb文件生成类似于ejb2.1部署模式的文件(包括必要的接口和部署描述符)然后再用类似于ejb2.1的方式来部署这个ejb组件。当然,这样产生的部署描述符可能并不标准但是它可以解决同一个容器对ejb2.1和ejb3.0兼容的问题。
·另一种方法是一种类似于jsp托放的部署模式。你可以把一个ejb文件放到一个预先定义的目录下,然后容器会识别这个ejb并处理它,然后部署并使之可以使用。这种方法可以建立于上面那种方法之上,在支持反复部署时有很大的帮助。考虑到部署的简单性也是ejb3.0规范的目的之一,我真诚的希望在下一个草案出来时能够确定一个模式(至少能有一个非正式的)。
你有什么想法?
ejb3.0规范的制定正在有序的进行,为了使 ejb的开发变得更加容易,ejb规范组织作出的努力是有目共睹的。就像他们说的那样,一切对会变得简单,但做到这一点并不容易。目前已经定义了50个注释标记(还有几个将在下一个草案中发布),每一个都有自己的缺省规则和其他的操作。当然,我真的不希望ejb3.0变成ejb2.1的一个翻版"ejb 3.0 = ejb 2.1 for dummies"(希望这个等式不要成立)。最后,我还是忍不住要提一些我自己的观点:
·首先,规范确实使反复部署变得容易了,并且有一个简单的模式来访问运行时环境。我还是觉得home接口应该放弃。
·在早期的ejb规范中,实体bean用于映射一个持久化存储。理论上(也许只是理论上)可能需要把实体bean映射到一个遗留的eis (enterprise information system)系统中。出于将来扩展的考虑这样作是有好处的,并且可以使更多的业务数据模型采用实体bean。也因此其伴随的复杂性使得实体bean不被看好。在本次提交的草案中,一个实体bean只是一个数据库的映射。并且是基于非抽象持久化模式和简单的数据访问模式的更加简单开发。
·我对模型变更持保留态度,我认为在ejb中包含sql脚本片断并不是个好注意。一些开发人员完全反对包含某些“sql片段(sqlness)”(比如 @table 和 @column注释)。我的观点是这些sqlness是好的,据此我们可以清楚的知道我们到底要数据库作些什么。但是某些sql段我看来并不是很好,比如 columndefinition="blob not null",这使得ejb代码和sql之间的耦合太过紧密了。
·尽管对于本地sql的支持看似很诱人,其实在ejb代码中嵌入sql是一个非常糟糕的主意。当然,有些办法可以避免在ejb中硬编码sql,但是这应该在规范中说明,而不能是某些开发人员自己定义的模式。
·假设@table注释只用于类。在运行时通过@table注释的name属性定义的表名称将必须对应一个实际的数据库表。规范对此应该给予清楚的说明和一致的模式。
·规范还需要更清楚的说明客户端编程模型,尤其是普通java客户端。规范中所有的参考都假设或者隐含的使用ejb客户端。而且规范中对客户端的向后兼容方面也没有给出明确的说法。
·transient注释应该重新命名以避免和已有的transient关键字发生冲突。事实上,在这一点上我们更乐于稍微的背离一下 configuration-by-exception原则并且定义一个@persistent注释来明确的定义持久化字段。@persistent注释可以仅仅是一个标记注释或者它可以有几个属性来关联o/r映射注释。
与其他规范的关联
目前可能影响到ejb3.0的jsr有jsr175(java语言元数据工具)和jsr181(java web服务元数据)
jsr175已经初步完成并且不会和ejb3.0有太大的冲突;但是jsr181与ejb3.0有两个关联的地方:
·web service接口:ejb规范将采用一种机制适应jsr181以便可以把一个bean实现为一个web service并告诉web service如何被客户端调用。
·jsr 181计划采用不同的机制来处理安全问题。在早期的规范中ejb建议使用一个一致的机制(methodpermissions),但是jsr 181计划使用一个稍微不同的方式(securityroles和securityidentity注释)。同样的runas注释的定义也存在这些许差别。这一问题还在解决中最终会在j2ee层的规范中维持其一致性。
在j2ee 1.5中的一些开发规范可能与ejb3.0有关联。除了上面说到的几个关联之外现在没有其他的开发规范与ejb3.0有冲突。
结束语
在使ejb的开发变得简单高效之前,我们还有很长一段路要走。规范组织在降低ejb的开发难度方面起了个好头。o/r映射模型的提议还处在早期阶段,规范组织正在完善它。我希望它不要太复杂也不要与sql过分的耦合。让我们不要只是停留在期望、希望、思考和请求中:提出你的想法并把你的建议发送给规范组织 [email protected]。jcp并不是很民主的组织,但是你的建议一定是有价值的。
新闻热点
疑难解答