EJB 2.1中的新特性主要集中于有关SOAP和WSDL的Web服务,包括两种新推出的Web服务应用程序接口(JAX-RPC和JAXM)。它们可以用来与其他Web服务模块通信,并适当地在Web模块中运用无状态的bean和消息驱动bean。也就是说,基于新的标准,EJB将逐渐成为Web服务的开发平台。
在支持Web服务的同时,EJB 2.1也改进了EJB-QL以及消息驱动bean(MDB)的编程模型。该编程模型目前已经扩展至Java消息服务之上以支持任何一种消息系统。另外,新标准也推出了一种新的计时器服务,使得开发人员可以设计计时事件,并提供消息联接的接口,供开发人员在组件之间控制消息的流动之用。
这里我们并不讨论每个特性的太多细节,只是想做一简单的介绍,起到抛砖引玉的作用。如果读者有兴趣,可以参阅EJB 2.1的相关规格说明。下面我们就Web服务、MDB编程模型和EJBQL三个方面分别加以说明如下:
(一) 对于Web服务的支持 EJB 2.1新标准推出的最大原动力就是对于Web服务的支持。EJB 2.1允许编程人员利用无状态的会话bean和消息驱动bean来开发基于SOAP的Web服务,并使得基于SOAP 1.1的用户可以使用相关的服务。
应该说明的是,基于其他Web服务平台的SOAP客户通常无法激活无状态的会话 bean的方法,例如MS.NET,PERL,Apache Axis。而在EJB 2.1中的Web服务接口则提供了一个前所未有的跨平台兼容性。
EJB 2.1中Web服务接口是基于两个新推出的J2EE SOAP技术的,即JAX-RPC和JAXM。
1、JAX-RPC和EJB JAX-RPC,即Java API for XML-RPC,是基于SOAP的Java RMI技术的。它与以前的 Java RMI技术和Java-RMI IIOP技术类似,不同之处是使用了SOAP作为底层协议。
实现JAX-RPC的系统必须支持HTTP之上的RPC编码机制,另外也应该支持其他的编码机制、消息格式和互联网协议。各种EJB,包括会话bean、实体bean和消息驱动bean都可以使用JAX-RPC技术来激活Web服务的操作。比如说,一个无状态的会话bean就可以利用JAX-RPC来调用.NET Web服务的方法(见下图1)。
图1 JAX-RPC 和 EJB
JAX-RPC同样也是一种新的组件接口的开发基础,这种接口称为终点(endpoint)接口,它允许一个无状态的会话bean作用为一个Web服务组件。终点接口实现了javax.rmi.Remote接口并遵循JAX-RPC的协议标准。其中,将一个无状态的会话bean作为Web组件来部署的过程并不是很复杂,开发人员只需要定义bean的类文件及远程接口,并将其部署至相关的应用程序中。一旦Web服务的组件部署成功后,其方法可以被任何一个遵循SOAP协议的组件调用,而无论组件是基于何种开发语言或开发平台的,如.NET,PERL,Apache Axis,C,C++及其他(见下图2)。
图2 通过SOAP和其他Web服务器通信
2、JAXM和EJB JAXM(Java API for XML Messaging)是一种类似于JMS(Java Message Service,Java消息服务)的消息通信的应用程序接口。JMS是一种用于在面向消息的中间件之上发送和接收消息的应用程序接口,而JAXM则是在Web服务中传递消息的应用程序接口。因为它主要以传输基于XML文件的SOAP消息为主,所以可以说JAXM是面向文档的。JAXM用户利用SAAJ(SOAP with Attachments API forJava)集成,接收和管理SOAP消息,其中SAAJ主要是用来管理SOAP消息中的XML结构。
JAXM技术与上面所说的JAX-RPC存在很大的不同,后者主要使用方法调用的机制,并在Java RMI代理(proxy)之间隐藏SOAP消息。基于JAX-RPC技术,开发人员只会看见远程接口,即方法、参数和返回值。而在JAXM的作用下,开发人员将直接处理SOAP协议并开发自己专用的SOAP消息。类似于JAX-RPC,JAXM可以用来与任何遵循SOAP开发的Web服务组件交换SOAP消息。比如说,一个enterprise bean可以利用JAXM来与用PERL开发的Web服务交换SOAP消息。
现在一些EJB 2.1开发人员推荐使用JAXM作为开发新的消息驱动bean的基础,即基于JAXM的消息驱动bean(JAXM-based message-driven bean,JAXM-MDB)。JAXM-MDB可以传输SOAP消息并作用为Web服务的组件。基于JAXM-MDB,开发人员可以实现单工的消息传输接口,或双工,即可接收可发送的消息传输接口(见下图3)。就目前来说,因为消息驱动bean组件可以广泛用到任意类型的消息系统,这种想法应该是可行的。
JAX-RPC和JAXM可以允许enterprise bean来访问其他平台的Web服务,并利用无状态的会话bean和消息驱动bean来开发相应的Web服务模块。这些应用程序接口是相对灵活的,适合于将EJB模块扩展为Web服务框架。
图3 JAXM-MDB
(二)扩展消息驱动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标准的服务器上移植的(如下图4)。
图4 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方法管理的。这种方法也可以使用可序列化的对象来区分不同的定时器。
(三)EJBQL的提高 EJB 2.1也包括两项对于EJBQL的提高,