1.2 EJB 3.1的新特性
EJB 3.0给Java EE 5带来了由重量级向轻量级的转变,而EJB 3.1是在EJB 3.0基础上将简单开发深入下去并增加了一些急需的特性,下面简单总结了EJB 3.1中的一些新特性。
● 引入单例
EJB 3.1之前,Session Bean被设计为单线程的模型,此模型要求同一时刻某一个bean的实例只能被一个线程使用,其中无状态会话Bean采用实例池,而有状态会话Bean采用激活钝化技术实现。在EJB 3.1中,通过@Singleton标记该Session Bean为Singleton,这样每个应用程序会确保只实例化一次,如下面的示例所示。
@Singleton public class MySingleton{ private Properties props; public String getProperty(String name) { … } @PostConstruct public void initialize { //props= … } }
● 提供了更强大的Timer Service
EJB从2.1版本就引入了定时的机制,但是一直到3.0,定时机制使用起来都不是很方便,比如要注入定时服务到bean中。EJB 3.1引入了申明式的定时服务,提供了编程和注释两种机制来进行定时服务,如下面的定义所示。
@Stateless public class MyTime{ @Schedules{ { @Schedule(hour=“10”) } public void MyTime(Timer time) { … } } }
●EJB接口是可选的
EJB 3.0中要求Bean至少实现一个接口,而在EJB 3.1中的Bean可以不需要接口,只要在相应的实体模型中标注上@Stateless或@Stateful就可完成Session Bean的功能。我们可以看一个从EJB 3.0中改过来的实例。
@Stateless public class HelloBean{ public String getHello() { … } }
● 异步服务
在EJB 3.1之前,在会话Bean上的任何函数调用都是同步的。而在EJB 3.1中支持异步函数调用的会话Bean,通过使用@Asynchronous注解的Bean函数实现异步调用。异步函数可以返回一个java.util.concurrent API的Future对象,当客户端想获取调用的状态时这个非常有用,通过检索函数返回值,可以检查一个异常或者取消调用。比如,在客户确认订单后,消息驱动Beans OrderBillingMDS异步地给客户开出账单,并且当支付完成后,更新订单信息,请看下面的示例。
@Stateless public class OrderBillingServiceBean implements OrderBillingService{ ... @Asynchronous public void billOrder(Order order){ try{ //Attempt to charge the order. bill(order); //Send email notification of billing success. notifyBillingSuccess(order); order.setStatus(OrderStatus.COMPLETE); }catch(BillingException be){ //Send email notification of billing failure. notifyBillingFailure(be,order); order.setStatus(OrderStatus.BILLING_FAILED); }finally{ update(order); } } ... }
由于使用了@Asynchronous标注,当客户端调用OrderBillingService.billOrder()方法时,调用会立即返回,而不会一直阻塞,直到billOrder方法执行完毕后才正常退出该方法。EJB容器会去确认哪些方法需要同步执行。请注意异步方法的返回值是void型的。不过,EJB 3.1还支持java.util.concurrent.Future<V>作为返回类型,其中V表示异步调用后,返回结果的类型,Future<V>接口允许我们做以下几类事。
● 取消异步调用
● 检查调用是否运行结束
● 检查是否有异常
● 得到异步调用后的结果
● 简化打包机制
EJB 3.0可选的XML部署描述符已经大大简化了JavaEE应用程序的打包和部署。尽管如此,JavaEE打包仍然必须分开为web和EJB模块打包成jar文件。EJB 3.0中的打包方式如图1.1所示。
图1.1 EJB 3.0打包方式结构图
在使用EJB 3.1后,开发人员可以直接将classes目录下的EJB和servlets一起打包到WAR文件中,如图1.2所示。
除了上述新特性外,EJB 3.1的特性还包括更简化的JMS,JavaMail和数据库注入,提供了接口服务的支持便于把第三方库整合进来,可运行的embedded的容器中便于Java SE环境进行JUnit测试。EJB 3.1中还定义了统一的全局JNDI命名方式,采用了统一的方式来获取注册的Session Beans,这样就避免了同一个应用程序中的那些Session Beans在不同供应商的容器中JNDI命名不同的问题。有关EJB 3.1更多的特性可从以下链接获得:http://jcp.org/en/jsr/detail?id=318。
图1.2 EJB 3.1的打包方式结构图