EJB 3.1从入门到精通
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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的打包方式结构图