简化开发者的观点
如果你使用现有版本的EJB你会懂得开发一个如HelloWorld的简单的EJB程序是多么困难。你至少需要两个接口,一个bean类和一个部署描述文件。大多数的开发者希望知道为什么我需要所有这些。IDEs(开发环境工具)象Oracle的JDeveloper, Eclipse和XDoclet简化了开发者的做这些普通的工作开发周期,可是在EJB在你部署到所选择的容器中之前,编译类和打包部署文件依然是开发人员的工作。
EJB3.0试图从以下方面简化复杂性:
· 不必定义接口和部署的描述文件,这些可以由容器使用metadata annotations生成。
· 使用常用的Java类作为EJB的类和常用的EJB业务接口。
元数据描述(Metadata Annotations)
EJB3.0非常倚重Metadata Annotations。Metadata Annotations已经成为JSR 175标准并且将是J2SE 5.0的一部分。Annotations是一种对象变成的属性,非常类似与XDoclet。可是不像XDoclet那样需要预先编译,Annotations由Java编译器在需要编译的时候编译。(依赖于@Retention的开始时间)。在开发人员的观点,Annotations就如同一个公有的并可以作为类,域,方法,参数,本地变量,构造,枚举和包一样使用的修改量。你可以在你的Java代码中附带特殊的属性使用Annotations来生成代码,自动编写文档代码,或者提供如在运行期间增强业务层安全或特殊业务逻辑的特殊服务。J2EE1.5(5.0)的目标是简化开发人员使用Annotations因此而可能产生一套的Annotations模板。Annotations使用@来标记,如下:
@Author("Debu Panda")
@Bean
public class MySessionBean
EJB3.0为了简化开发因此使用Metadata Annotations来产生许多如接口一样的人为因素和使用Annotations来替代部署描述文件。
使用 POJOs 和 POJIs
在规范条件中,JavaBeans和接口经常分别的涉及到简单Java对象(POJOs)和简单Java接口(POJIs)。这些不必要的如Home接口的人为因素已经被去掉。
开发人员必须在javax.ejb包中实现一个EJB接口(会话bean,实体bean或消息驱动bean)或者选择在bean的实现类中使用Annotation。你可以使用无状态,状态,消息驱动或者实体去注释一个bean类。例如,如果你定义一个无状态EJB作为HelloWorld,你可以如下定义EJB:
@Remote
@Stateless public class HelloWorldBean {
public String sayHello(String s)
{ System.out.println("Hello: "+s; }
}
EJB的接口无论远程的还是本地的都不必再实现EJBObject和EJBLocalObject。你要么为EJB提供业务接口并且实现bean类中的接口,要么需要在部署的时候生成这些接口。虽然会话bean和消息驱动bean的接口是必须的,但是实体bean的接口是可选的。如果你没有为你的会话bean实现一个接口,那么它会自动为你生成一个。所生成的接口是本地的还是远程的取决于你在bean类中的Annotations。如果你仔细看看上面的代码范例,@Remote很明显是用来为你的HelloWorld生成一个远程接口。如果需要,你可以在你的EJB中同时生成远程和本地接口。
在上面的例子中,很明显开发人员不必再做那些如定义接口和实现回滚方法等这些普通的工作。
生成接口的名字来源于bean实现类的名字。生成接口对开发人员来说非常有用。但是我并没有看到任何如Oracle 的JDeveloper的这些IDE立即实现这种生成接口功能。
规范中没有明确EJB查找时客户端的需求是什么,也没有明确我们如何保持这些EJB需要调用的接口。基于以下几个情况下的原因我将不推荐使用生成接口:
· 生成接口的名字来源于bean的名字
· 如果你不愿意在EJB中暴露出一些方法而生成接口将默认暴露出所有的方法。
· 你需要在客户端使用接口来调用EJB.
去掉回滚方法的需求。
EJB2.1和更早版本需要实现很多即使对于每个EJB你不需要的一些生命周期的方法,如ejbPassivate, ejbActivate, ejbLoad, ejbStore等等。例如,在无状态会话bean中不需要ejbPassivate但是你还是得实现它的方法。现在EJB3.0中类似的常用Java类实现这些生命周期的方法都变成为可选择的。如果你在EJB中实现任何回滚容器都会调用这些方法。
唯一的异常是在你可以使用Remove的annotations时一个状态会话bean的业务方法的ejbRemove方法是状态会话bean。如果你使用这个annotations它将在完成annotations方法后(无论正常或非正常)提示容器移除状态会话bean实例。例如,你可以指定以下的方式去在checkOut方法执行后移除一个状态会话bean实例。
@Stateful public class Cart {
...
...
@Remove public void checkOut() {
...
}
}
Annotations与部署描述的比较
在前面我们讨论到EJB中不再需要部署描述而由annotations代替。每个部署描述的属性都将被选择一个默认值,而开发人员在直到他们想改变这些属性的默认值之前不必为这些属性指定值。这些也能用来为bean的类自身指定使用的annotations。EJB3.0规范为开发人员使用bean类型,接口类型,资源引用,事务属性,安全等等定义了一组metadata annotations。例如,如果我们可以如下为一个特殊的EJB定义使用资源引用:
@Resource(name="jdbc/OracleDS", resourceType="javax.sql.DataSource")
J2EE的提供商如Oracle, BEA, IBM将增加属性annotations在他们指定的部署描述中,开发人员将可以使用这些annotations去避免使用部署描述。这看起来对开发人员十分具有吸引力,特别对XML描述是已经感到厌恶的开发人员,他们早就恨透并想脱离老的那种描述方式,但依然有一些问题使得我们在正式使用annotations时需要谨慎对待。
它违背了我们轻便应用程序的目标,因为如果一个EJB如果使用一个提供商指定的部署描述,在重新编译或打包EJB的时候它必须多次改变。
部署描述对EJB模板提供了全局观点使得组装和部署的时候不必考虑单独的EJB,他们将每个部署需求拧在一起,并且在部署完成之前描述是无效或者不可自动生成的。这对部署员来说是个可怕的事情。
部署描述在EJB模板中被相关工具用来定义EJBs,当你试图整合一个和另一个容器的时候非常有用。EJB3.0规格同样主张在部署描述中使用重载annotations的方式。可是在规范里并没有提到重载annotations的细节。
无疑摆脱部署描述将使得新的开发者开发更加容易,但是如果使用不当这也将造成管理上的可怕问题。