MessageDrivenBean容器服务
EJB容器提供了下列服务,它们都是低级的EJB支持的服务,不能直接被使用EJB1.1的JMS开发者使用。
1.治理生命周期:
MessageDrivenBean的生命周期与配置它的EJB服务器的寿命是一致的,因为MessageDrivenBean是无状态的,所以组件实例通常被EJB服务器集中起来,并且当一条消息变得对于作为消息消费者的主题或队列可用的时候,会被容器取回。
2、处理异常:
MessageDrivenBean组件当处理消息的时候,可能不会抛出应用程序异常,这就意味着可能被MessageDrivenBean抛出的唯一的异常指明一个系统错误的运行时间异常。容器将会处理这个异常,方法是删除这个组件实例,并返回任何组件实例或容器启动的事务处理。
3、线程或并发性:
MessageDrivenBean实例是在一个单独的控制线程中执行,这将大大的简化开发者的任务。EJB服务器将确保这一特性,另外,EJB服务器可能提供一种操作模式答应多消息被单独的组件实例同时处理,这个配置选项实用定义在JMS规范中的“eXPert level”类。JMS提供者并不一定带有这些类,所以EJB服务器可能不能利用每一种JMS实现的这种功能。
4、事务处理:
就像使用entity或session组件一样,MessageDrivenBean组件也可以有“contain-or-bean-managed”(容器或组件治理)事务处理。一个事务属性可以设置为MessageDrivenBean组件的onMessage()方法。因为没有客户端事务处理,所以只有一个事务处理属性的子集考虑到entity和session组件与MessageDrivenBean组件有关系。使用了容器治理事务处理。容器将能支持MessageDrivenBean的Required和NotSupport事务处理属性。一个带有组件治理事务处理的MessageDrivenBean组件可以使用JTA UserTransaction对象。这个MessageDrivenBean组件在从onMessage()方法返回之前,必须先结束事务处理。onMessage()方法非常简单,它带有容器治理事务界限和NotSupported事务属性。容器将不会创建事务并且组件开发者被禁止访问 UserTransaction对象。
更有趣的事,当onMessage()方法被指定了Required事务属性,这时容器将创建一个全局事务处理收集任何可参考的资源并被传递到任何其他的正在处理消息的EJB服务器上。这是唯一一种JMS主题或队列接口包含于EJB事务处理中的情景。
对于使用Required事务属性的组件,JMS服务器将成为XAResource,假如JMS服务器提供者不支持XA事务处理,JMS session通常将与容器的全局事务处理的结果同步。这样,容器将不能包括用于治理分布事务的两方面的委托处理的JMS服务器。JMS session的一个 rollback(反转)将警告 JMS服务器,消息应当被重新发送。
5、消息确认:
容器总是处理MessageDrivenBean组件的消息收到的确认,对于组件来说,使用定义在 JMS规范中的客户端消息收到确认方法是非法的。消息收到确认可以被设置为 DUPS_OK_ACKNOWLEDGE或 AUTO_ACKNOWLEDGE,前者答应在一次失败之后投递消息的副本,而后者提供一个严格的保证机制,确保消息只能被投递一次。
6、安全性
因为MessageDrivenBean组件没有客户端,所以在接受消息的时候容器基本上不会产生安全问题。EJB2.0规范中为组件方法执行一个声明指定的功能提供了方便。因此,MessageDrivenBean组件可以被设置来确保用于传送到其他正在处理消息的EJB服务器的安全。这就可以使MessageDrivenBean组件维护方法级安全性了。
应用程序服务器框架
当 MessageDrivenBean提供的功能在应用程序服务器内被部署好后,它就会以指数形式膨胀开来。一个高端的应用程序服务器提供可扩展性,负载平衡,动态应用程序启动,附加的 EJB服务器实例的动态配置以及容错性,这些都是企业级应用程序的核心要素。
1、可扩展性: 企业级应用程序服务器的一个要害元素就在它的提供一个结构来适应不断增加的处理负载的能力。 随着被 MessageDrivenBean处理的消息的数量的增加,应用程序服务器的 EJB服务器必须使适应这些增加而不会明显的增加处理时间。一般是提供给多应用程序服务器用于协调处理受到的消息的增多,这样应用程序服务器就有了可扩展性了。
2、负载平衡:当一个请求发送到应用程序服务器,一个负载平衡元素可以在实例之间平均分配负载(见图六)。举例来说,应用程序服务器每个实例都可能包含一个EJB服务器的实例。使用应用程序服务器的负载平衡特性,受到的消息就可以平均分配到所有的EJB服务器实例上了。
3、动态应用程序启动:应用程序服务器应当可以在负载增多时启动附加的预先设置的实例。
4、动态设置额外的EJB服务器实例:即使一个应用程序被设定了固定的用于处理应用程序负载的实例数,但是也有可能信息流的激增造成系统处理速度变慢,为了处理这种情况,应用程序服务器必须具有配置附加应用程序实例的特性。比如说,应用程序服务器可以答应系统治理员动态定义附加的EJB服务器实例并把这些附加实例部署到EJB服务器中。负载平衡元素将利用这些补充的实例来处理消息。
5、容错性:一个企业级的应用程序服务器必须也具有能够适应出错的情况,像网络或硬件上的问题,但是前提是不能明显降低系统性能或是丢失数据,应用程序服务器使用的一种方法就是通过设置多应用程序服务器实例来分配状态信息,收到的消息通过智能化的负载平衡元素被分配到实例上。假如有一个或多个实例不能到达,负载平衡元素只要简单的把消息重新分配给各个能用的实例就可以了。此外,负载平衡元素还可在治理组件的参与下重启那些因为某些原因而不能使用的实例。
超越JMS
EJB的MessageDrivenBean组件部分给企业级服务器领域又添了一员猛将,它答应消息经由JMS接受在被一个简单但又强有力的组件处理。然而,MessageDrivenBean的EJB组件事实上有能力变成能够处理任何消息的组件模型,而不单是JMS服务器发来的消息。
JMS消息通过JMS实现被变成可交互操作,这就意味着JMS消息私地下是某一种特定的的实现,但是内容可以完全透明的被转换成另一种特定的JMS实现而不会在任何方面影响消息消费者。因此任何消息格式都可以转换成为JMS消息并被传递到MessageDrivenBean组件中。换句话说,一个MessageDrivenBean组件可以处理电子邮件、HTTP、FTP或其他任何协议发来的消息,以及又具有把这些协议转化成为JMS消息的应用程序服务器提供的消息。这就开启了一个标准、简单、轻便且能够处理任何协议发过来的任何消息的能力的组件模型之门。假如消息被定义成为可开发的、可扩展的语言向XML这样的及其强大的可交互操作在宽松连接系统以一种每个人都能理解的模式完成。下面我想简单以一个独立于协议以外的消息处理的例子来验证一下这种技术的强大威力。
一个B2B的例子
一个典型的B2B情景就像一个“中枢-轮辐”形,多个宽松连接的商家(即“轮幅”)与一个大型企业(即“中枢”)交互连接,在某种情况之下,当执行交互操作(像发送大的订单这样的事件)可以经由JMS应用程序在大企业与商家之间正常相互作用。对于一些小型商家来说,采用纯JMS可能在成本上太高而负担不起,它可能会采用通过Web浏览器中的HTTP或发送电子邮件的形式向大企业发送订单。为了向客户开放B2B系统,大型企业级服务器就必须能够处理这一系列不同的协议。
而且,作为中枢的大型企业级服务器虽然接受来自email或来自JMS等不同类型格式的订单,但是只有必要为每一种方式分别编写处理程序。使用MessageDrivenBean组件,任何协议都可以发送以XML格式描述的订单,如下面的例子。MessageDrivenBean组件只需要把注重力集中在处理来自应用程序服务器发送的JMS TextMessage中的XML就可以了,而不要去关心到底所处理的消息时直接来自JMS服务器还是作为一条来自邮件服务器的SMTP消息。
代码段六:
<purchase_order>
<client_number>101</client_number>
<date>August 8, 2001</date>
<billing_address>
<name>Wayne Zheng</name>
<address>xyz street</address>
<city>Hefei</city>
<province>Anhui</province>
<zip>230027</zip>
</billing_address>
<shipping_address>
<name>Zhang Tao</name>
<address>Huangshan Road</address>
<city>Hefei</city>
<state>Anhui</state>
<zip>230026</zip>
</shipping_address>
<items>
<item>
<quantity>1</quantity>
<prodUCt_number>324</product_number>
<description>Java Book</description>
<unitcost>19</unitcost>
</item>
<item>
<quantity>1</quantity>
<product_number>532</product_number>
<description>Java VM</description>
<unitcost>56</unitcost>
</item>
</items>
</purchase_order>
小结
EJB2.0提供了一种新的组件模型-MessageDrivenBean组件-用来处理异步消息,MessageDrivenBean组件可以简单的开发和利用与其他EJB组件模型相同的容器服务,这种新的组件模型答应整合面向对象的中间件(MOM)的、优秀的以及新一代纯Java的JMS。并且,MessageDrivenBean组件还有可能成为处理任何异步消息,非凡是基于XML消息的工业标准。因此,MessageDrivenBean组件是EJB2.0中的非常重要的一员,本文只是初探其面目,以后我还会更加深入的探讨其的功用。