会话bean与JMS
将会话bean与JMS结合起来使用是一种可行的面向企业的解决方案。会话bean被设计用来履行对业务服务的请求。必须查询企业消息传递系统来履行这样的一个请求,就这一点来说,企业消息传递系统可以由一个会话bean透明地来访问。使用会话bean作为JMS客户机还允许将JMS通信合并到一个大型企业事务的上下文环境中。例如,可以建立一个J2EE事务来从一个JMS提供者那里获取一条消息,从该消息中提取数据,并尝试更新数据库。如果更新操作失败并且事务回滚(rollback),则再发送一条消息到一个单独的目的地上的JMS提供者那里,同时给出对事务失败的原因的描述。
企业JavaBeans 技术使用资源管理器连接工厂来访问额外容器(extra-container )资源。这些资源是标准的企业组件,但不是J2EE容器的核心部分,它们包括数据源、JMS会话、JavaMail会话、URL连接以及Java连接器体系结构( Java Connector Architecture ,JCA)适配器。资源管理器是J2EE容器的一个组件,它管理着某一特定类型的资源的整个生命周期,这些资源包括连接池、事务支持以及实现实际连接所必需的任何网络协议。
企业bean通过三个步骤来获得一个JMS会话的连接:通过JNDI查找获得一个连接工厂引用,通过工厂引用获得一个连接,然后以一种常规的JMS的方式使用主题或者队列连接对象。因为JMS必须有遵从J2EE规范的应用服务器的支持,因此不再需要附加的库或者组件。
JMS会话bean 的优点和缺点
将JMS和会话bean结合起来使用,这在企业功能性方面是一个进步,而在简单性和灵活性方面却又是一个退步。通过使用会话bean,应用开发者可以访问EJB容器所提供的整个范围的J2EE功能,包括JNDI、宣告式事务语义、自动并发支持、资源管理、宣告式安全性以及对诸如实体bean、数据源、JavaMail和JCA适配器之类的企业资源的访问。从消息传递的立场来看(跟MDB不一样),会话bean与JMS的联手并没有对您的bean所能访问的主题和队列强加任何数量上的限制。
作为增强企业特性的代价,您牺牲了简单性,客户机占用空间(client footprint)也不再像以前那么小了,而且也没有了异步性。前两项损失倒没什么好奇怪的,如果您已经关注探索者系列有一段时间了,那么您就更能理解这一点。会话bean要求有一个成熟的J2EE EJB容器,这让您的开发小组(针对EJB开发而言)和您的整个系统体系结构(针对客户机占用空间而言)背上了沉重的包袱。
异步性是使用像JMS这样的企业消息传递技术的主要优势之一,而且,在取得这一优势的同时它并没有失去什么。有了JMS,消息传递客户机可以通过提供者发送消息,消息发送出去之后便可以离线,而让提供者从容地传送这条消息。接收消息的客户机可以周期性地上线并检查新的消息,或者也可以设立一个侦听器组件,令其一直处于在线状态以等待来自提供者的消息。会话bean是同步的,因而不能支持“一直在线(always-on)”侦听器组件。与前一种客户机不同,同步的Java客户机必须调用一个会话bean方法。然后由该会话bean方法打开与一个消息传递提供者的连接,以便发送和接收消息。
消息驱动bean
EJB 2.0 规范定义了一种新的企业bean,以期弥补其他四种类型的企业bean(两种会话bean和两种实体bean)的不足。这种新的bean就是消息驱动bean(message-driven bean,MDB),人们期望用它来提供可重用的消息传递组件,以便利用已有的在J2EE应用服务器方面的投资,尤其是利用已有的EJB技术。
MDB 只能通过一条JMS消息异步地进行调用。因此,它并不具有其他bean所具有的本地和远程接口。相反,MDB实现两种特殊的接口:一个与EJB容器之间的接口(javax.ejb.MessageDrivenBean),以及一个消息传递接口(javax.jms.MessageListener)。作为一种成熟的JMS客户机,MDB通过一个MOM服务器既可以发送消息,又可以接收消息。作为一种企业bean,MDB由容器来管理,并且通过一个EJB部署描述符进行宣告式的配置。
MDB 的优点和缺点
MDB允许开发者利用已有的在EJB技术方面的投资,但是仍然可以将这些投资整合到一个异步消息传递的上下文环境中。例如,JMS客户机可以发送一条消息给一个MDB(该MDB一直在线等待传进来的消息),而后者可以访问一个会话bean或者一些实体bean。通过这种方式,MDB可以被用作一种异步包装器,提供对业务流程的访问途径,而之前这些业务流程只能通过一个同步的RMI/IIOP调用来访问。
消息驱动bean本身也是一种强大的消息传递解决方案。由于MDB被专门设计用来作为消息的消费者,并且仍然是由EJB容器管理的,因此它们在可伸缩性方面提供了巨大的优势。由于消息bean是无状态的,并且由容器进行管理,因此它们并发地发送和接收消息(容器只是简单地将另一个bean从池中提出)。这一点,加上EJB应用服务器所固有的可伸缩性,构成了一种极其健壮的、可伸缩的企业消息传递解决方案。
另一方面,MDB相对来说还是一种很新鲜的事物,没有经过很多的检验。因而,并不是所有的J2EE供应商都支持它们,即使是支持MDB的那些供应商也只是最近才实现它们的。可以预见,MDB的不成熟意味着供应商实现在稳定性和可靠性方面还有一段很长的路要走。而且,MDB社区也需要经历更多的锤炼,以获得一套成形的使用MDB的非常好的实践。
抛开MDB的相对不成熟性不提,理解它是为专门的目的而设计的(即作为JMS消息的消费者)十分重要。MDB只能通过JMS消息来调用,其他方式都不管用。这意味着它们作为消息的消费者非常理想,但未必适合作为消息的生产者。消息驱动bean当然可以发送消息,但前提是它首先要让一条传进来的请求调用它。而且,当前设计的MDB只能映射到单个的目的地。它们只能在那个目的地上侦听消息。这一限制在以后的版本中可以改变,但目前您只能为每个您想侦听的目的地定义一个MDB。