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服务的方法(见下图4)。
图4 JAX-RPC 和 EJB
JAX-RPC同样也是一种新的组件接口的开发基础,这种接口称为终点(endpoint)接口,它允许一个无状态的会话bean作用为一个Web服务组件。终点接口实现了javax.rmi.Remote接口并遵循JAX-RPC的协议标准。其中,将一个无状态的会话bean作为Web组件来部署的过程并不是很复杂,开发人员只需要定义bean的类文件及远程接口,并将其部署至相关的应用程序中。一旦Web服务的组件部署成功后,其方法可以被任何一个遵循SOAP协议的组件调用,而无论组件是基于何种开发语言或开发平台的,如.NET,PERL,Apache
Axis,C,C++及其他(见下图5)。
图5 通过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,开发人员可以实现单工的消息传输接口,或双工,即可接收可发送的消息传输接口(见下图6)。就目前来说,因为消息驱动bean组件可以广泛用到任意类型的消息系统,这种想法应该是可行的。
JAX-RPC和JAXM可以允许enterprise bean来访问其他平台的Web服务,并利用无状态的会话bean和消息驱动bean来开发相应的Web服务模块。这些应用程序接口是相对灵活的,适合于将EJB模块扩展为Web服务框架。
图6 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标准的服务器上移植的(如下图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方法管理的。这种方法也可以使用可序列化的对象来区分不同的定时器。
三)EJBQL的提高
EJB 2.1也包括两项对于EJBQL的提高,即order by语句的加入和一些新函数。
1、order by语句
以前的EJB规格描述中并没有包含order by语句,而在EJB
2.1中,EJBQL已经开始支持order by语句的应用了。比如说开发人员可以设计一个数据库用户信息查询,并将查询结果按照用户的系统ID排序:
SELECT OBJECT(I)
FROM Users as I
ORDER BY UID
order by语句通常会写在EJB远程或本地接口的查找(finder)或选择(select)语句中。通常来说在order
by语句的标识符(identifier)都是路径表达式(path
expression),并以容器管理的持久性变量结束。这里需要说明的是,order
by语句只能应用于相关ejb的容器管理的持久性变量。在order
by语句中,开发人员也可以使用DESC或ASC来指定排列结果时下降或上升的次序,其中上升次序是缺省值。
开发人员也可以在select方法中,即选出持久性变量时使用order
by语句。在下面的例子中,该查询选出了具有特定住址的用户,并按照姓名排序:
SELECT DISTINCT
I.customer.name
FROM Customer as I
WHERE I.city=
NanJing
ORDER BY I.customer.name
当一个EJBQL查询选出持续性变量时,order
by值应用于在该选出语句(select)出现的持续性变量。比如说,在上例中,开发人员无法先选出用户的姓名,而是使用用户的年龄进行排序。
2.新功能
新的EJBQL对于where语句和select语句都加入了一些新的函数。在where语句中,除了已有的concat,substring,locate,length,abs和sqrt函数,EJB2.1加入了mod函数。
EJB 2.1也同时向select语句中加入了5个新的集合类函数:AVG,COUNT,MAX,MIN和SUM,这些函数的功能都和SQL-92中相应的定义类似。不同的是,AVG和SUM只作用于数字类型,而COUNT,MAX和MIN函数则作用于任意一个容器管理的持久性变量,包括日期类型和字符串类型。Count则可以应用于一个容器管理的持久性变量或是EJB标识符。
比方说,我们可以定义一个查询,以得到所有住在南京的用户。这里COUNT函数直接地作用在标识符上,而无需OBJECT()操作:
SELECT COUNT(C)
FROM Customer as C
WHERE C.city=
NanJing
下面的例子中,我们可以得到用户工资的总和:
SELECT SUM(C.totalsalary)
FROM Customer as C
WHERE C.city=
NanJing
以上我们简要地介绍了EJB 2.1中的新特性,包括Web服务、消息驱动bean和
EJBQL等方面的提高,有兴趣的读者也可以参照最新的EJB规范描述来进一步研究和实践。
作者:务实,多年从事J2EE网站及应用系统项目的开发和应用。 |