二)扩展消息驱动bean
EJB 2.0引进了消息驱动bean,可以处理遵循JMS多方的异步消息。基于消息驱动bean,J2EE平台可以利用异步消息机制,并改变了服务器编程的体系结构。
EJB 2.1将基于JMS的消息驱动bean编程模型扩展为其他消息系统。基于EJB2.1开发的应用系统仍必须支持基于JMS的消息驱动bean(JMS- MDB),当然也支持其他类型的消息系统。比如说,一个Web服务模块可以支持基于JAXM的消息驱动bean,该模块也可以支持SMTP信件协议、 SNMP的设备控制、peer对peer的协议。另外,消息驱动bean也可以作为连接相关OLTP系统如CICS,IMS,openUTM的桥梁。
另外还要说明一点,由于新推出的消息驱动bean组件是基于J2EE连接器体系结构的(Java Connector Architecture,JCA1.5),所以该组件具有在消息系统之间良好的移植性。JCA 1.5通常是用于定义商业信息系统中的可移植程序模型。比如说,开发人员可以利用JCA 1.5定义一个基于SMTP的消息驱动bean,而该bean是可以在所有遵循EJB 2.1标准的服务器上移植的(如下图7)。

图7 JCA 1.5
1、目标链接(destination linking)
EJB 2.1另外一个新特性就是目标链接。简单地说,EJB容器可以将一个消息服务的输出传送至另一个消息驱动bean的输入,即新目标。
比如说,一个无状态的会话bean可以使用JMS发送一条异步消息到相应的目标,而在部署应用系统的时候,开发人员可以将该目标连接到一个部署在同一个 EJB容器的消息驱动bean。也就是说,开发人员可以使用目标链接技术在部署期间定义消息流动,从而在商业平台描述完整的工作流。
2、定时器服务机制
定时器服务机制是一个在EJB容器开发的调度系统。一个无状态的会话bean或实体bean可以在相应的定时器中登记,从而在未来一定的时间点被定时器通知。
定时器服务机制使用的是一个简单的程序框架。作为其基础的无状态的会话bean 或实体bean必须实现TimedObject接口:
public interface javax.ejb.TimedObject{
public void ejbTimeout(Timer timer);
}
当一个bean的相关时间点到达的时候,容器将会调用定时器的ejbTimeout()方法在这个方法中,开发人员将根据需求定义其应用逻辑。比如说,一个关于用户信息的实体bean具有一个每隔60天触发的定时器,以用来提醒用户应该修改密码。这样的话,每隔60天,EJB容器就会调用该定时器的ejbTimeout()方法,而这个实体bean就会向相关的mailer模块发送一条JMS消息,后者将会向用户的电子信箱发送要求修改密码的 email。Timer对象还具有一些其他特性,比如可以取消一个已定的定时器,查询在触发之前还有多少时间等。另外,开发人员还可以将一个定时器对象联系到一个可序列化的对象,从而在定时器中存储一些与应用相关的信息。当定时器响应的时候,开发人员可以访问一定的应用信息并决定如何处理相关的时间。
EJB可以通过TimerService接口来访问EJB容器的定时器服务,也就是说实体bean和会话bean必须使用该接口来设定它们自己的定时器。为了达到这一目的,bean必须首先调用EJBContext.getTimerService()方法的程序示例如下:
……
public interface javax.ejb.TimerService{
public Timer createTimer(java.util.Date expiration,
java.iO.Serializable info);
public Timer createTimer(java.util.Date initialExpiration,
long intervalDuration,java.io.Serializable info);
public Timer createTimer(long duration,
java.io.Serializable info);
public Timer createTimer(long initialDuration,
long intervalDuration,
java.io.Serializable info);
public Collection getTimers();
}
……
在一些情况下,开发人员只需要定时器在特定的时间响应一次,而在其他一些情况下,则需要定时器间隔一定时间持续响应。比方说,上面我们提到的ejb就会每隔60天提醒用户,也就是每隔60天的时间间隔就会响应一次。
一个无状态的会话bean或是实体bean可以设定多个定时器,但是一般来说它们都是由相同的ejbTimeout方法管理的。这种方法也可以使用可序列化的对象来区分不同的定时器。
