您现在的位置是: 软件 > 开发者网络 > 程序方舟 > Java专栏 > 正文


-Win xp中的多种网络
-试验试验试验试验
-用Freehand实现位图矢量化
-网络电话面面观

深入探讨EJB中新的消息驱动组件
2001-09-24· ·wayne··yesky

上一页  1 2 3 4 5 6  下一页


  MessageDrivenBean组件

  MessageDrivenBean被部署成为总是扮演信息消费者角色的客户端。MessageDrivenBean没有客户端视图,这就意味着其本地和远程调用接口都是不可用的。一个消息产生者发信息给一个主题或队列并且没有认识到一个事实--MessageDrivenBean正扮演着消息消费者的身份。这就导致了在基于系统的 JMS之间的宽松联结,并更多的考虑到了在集合一个分布式计算环境时应有的灵活性。

  MessageDriven 组件没有对话状态,其实所有的组件实例当它们在没有处理消息时都是等价的。这有点和无状态的session组件的状态特征有些类似。把组件实例集中起来是管理MessageDriven组件实例的普遍而又有效的办法。

  MessageDriven 组件必须以直接或间接的方法从接口javax.ejb.MessageDrivenBean中取得,而这个接口类则是从javax.jms.MessageListener接口得来并添加了两个方法。onMessage()方法是从javax.jms.MessageListener接口中继承来的,这个方法有唯一的参数,就是javax.jms.Message,可以是任何有效的JMS消息类型。这个方法显然不包括throw(抛出)子句,所以在处理消息时不会抛出任何应用程序异常。

当这个容器接收到消息,它首先从一个可用实例池中取得一个MessageDriven组件(见图4)然后把部署描述器中制定的任务与执行线程联系起来,使其能够传播安全上下文。此外,如果部署描述器需要事务上下文的话,容器也会设置与之的关联。



  一旦完成了管理任务,接收到的消息酒杯传送到MessageDrivenBean实例的onMessage()方法中,而一旦这个方法完成后,消息所载的事务就会被执行或返回,然后组件重新返回可用实例池中。

  当MessageDrivenBean实例被从容器中(通常从实例池中)的任何强的参考中逐出,都会调用ejbRemove()方法。ejbRemove()方法将释放任何被组件实例占用的资源。setMessageDrivenContext()方法有一个参数--javax.ejb.MessageDrivenContext类的一个实例。MessageDrivenContext类与定义在EJB1.1中的entity和session类有点类似,当一个组件实例被创建,容器就把它传递进一个实例占用的上下文中,这个类有取得环境信息的方法也有相应的方法取得JTA UserTransaction类(用于管理事务定界的组件)。

  此外,组件提供者还应当在EJB2.0服务器中可摄制的组件提供一个没有参数的ejb.Create()方法。这个组件实例可以获得任何在ejb.Create()用于进行处理的所需要的资源,比如说,在这一点上,MessageDrivenBean实例可以取得一个数据库连接,如果ejb.Remove()方法被调用的话,它将关闭或释放。

  值得注意的是,MessageDrivenBean现在已经大大的简化了创建JMS消息消费者的过程,下面的代码段3就创建并配置了一个EJB容器所委托创建的JMS消息消费者。开发者现在可以很容易的实现MessageDrivenBean接口,并可以把它配置在EJB服务器中且可以用来创建一个可收集消息的商业组件。

  代码段3:

/**

*MessageDrivenBean接口由每一个消息驱动企业级组件类实现。

*这个容器使用MessageDrivenBean 方法来通知

*企业级Bean实例的实例生命周期事件

*/



public interface javax.ejb.MessageDrivenBean extends

javax.jms.MessageListener

{

/**

* 传送一个消息给监听者

*

* 参数 message :Message对象。

*/

public void onMessage(javax.jms.Message message);

/**

*容器在结束消息驱动对象的生命周期之前,调用这个方法。

*/

public void ejbRemove();



/**

*设置相关联的消息驱动上下文。

*容器在创建了实例后调用这个方法。

* 企业版 Bean 实例将保存context对象的参考到一个实例对象中

*/

public void

setMessageDrivenContext(

javax.ejb.MessageDrivenContext context);

}

  在代码段4中给出了一个MessageDrivenBean实例的实现,在个组件从一个JMS TextMessage中取得一条字符串,并输出,它是根据代码段2种的JMS消息监听者程序改编的。

  代码段: 4

/**

* 这个类是 MessageDrivenBean的一个实现。

*/



public class MyListenerMDB implements MessageDrivenBean

{

/**

* 这是一个无参数构造器,这样 EJB容器可以使用Class.newInstance()方法来创建组件实例

*/

public MyListenerMDB()

{

}

/**

*这个方法接受消息实例并执行消息处理过程。

*

* 参数:message 。Message对象

*/

public void onMessage(Message message)

{

// onMessage 实现仍然未变:

// 从message对象中取出股票报价。

// StockQuoteProducer 发送 TextMessages

// 并在适合的时候放出该对象。

try

{

String quote = ((TextMessage)message).getText();

System.out.println("股票报价: " + quote);

}

catch(JMSException e)

{

System.out.println(

"不能处理消息: " + message);

}

}



/**

* 当MessageDrivenBean实例被从容器中抛出,该方法就被调用。

*/

public void ejbRemove() throws javax.ejb.EJBException

{

System.out.println(

"StockListenerMDB: ejbRemove被调用。");

}



/**

* 设置MessageDrivenContext实例。本方法将在组件实例化时被调用

*消息驱动上下文允许组件开发者访问EJB容器的工具

*

* 参数ctx : 消息驱动上下文

*/

public void setMessageDrivenContext(

MessageDrivenContext ctx) throws javax.ejb.EJBException

{

System.out.println(

"StockListenerMDB: setMessageDrivenContext 被调用。");

}



/**

* ejbCreate with no args required by spec, though not

* enforced by interface

*/

public void ejbCreate()

{

System.out.println(

"StockListenerMDB: ejbCreate called.");

}

}

  部署描述器

  MessageDrivenBean可以使用XML部署描述器来指出受EJB服务器信息控制的运行时间动作,下面是部署描述器中定义MessageDrivenBean的有效的DTD元素。

<!ELEMENT message-driven (description?,

display-name?, small-icon?,

large-icon?, ejb-name?, ejb-class,

transaction-type, transaction-scope?,

jms-message-selector?, jms-acknowledge-

mode?, message-driven-destination?,

env-entry*, ejb-ref*, security-

identity?, resource-ref*, resource-

env-ref*)>



  需要注意的是,部署描述器包含所有除用来部署MessageDrivenBean组件的目标名以外的所有信息,目标名被设置在一个应用程序服务器提供商指定的配置文件中或作为一个系统属性。

  在部署描述器中,配置器可以指定组件是倾向于用于主题还是用于队列,并且,如果倾向于用于主题那么组件是否应该担当持久的签署者( durable subscriber)的身份。像队列一样,持久的主题保证监听者将接收到所有发布到这个主题的消息,即使监听者可能一段时间都不可用。 持久的主题对应用程序的可靠性很重要。

  我们的给出的MessageDrivenBean的部署描述器(见代码段5)告诉容器这个组件是特意侦听一个不持久主题。这个组件有使用 NotSupported方法事务属性的容器管理事务限定。

  代码段5:

<ejb-jar>
<enterprise-beans>
<message-driven>
<ejb-name>MessageListenerMDB</ejb-name>
<ejb-class>messageListenerMDB</ejb-class>
<transaction-type>Container</transaction-type>
<transaction-scope>Local</transaction-scope>
<jms-acknowledge-mode>auto-acknowledge</jms-
acknowledge-mode>
<message-driven-destination>
<jms-destination-type>javax.jms.Topic</jms-
destination-type>
<jms-subscription-durability>nondurable</jms-
subscription-durability>
</message-driven-destination>
</message-driven>
</enterprise-beans>
<assembly-descriptor>
<container-transaction>
<method>
<ejb-name>MessageListenerMDB</ejb-name>
<method-name>onMessage</method-name>
<method-params>
<method-param>javax.jms.Message</method-param>
</method-params>
</method>
<trans-attribute>NotSupported</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>

  使用MessageDrivenBean组件的另一个好处就是它的部署的简洁性。 典型情况下,一个应用服务器供应商将提供定义组件部署描述器的工具,产生 EJB jar文件,并且部署组件。 一旦组件部署好了, EJB服务器将处理 EJB容器类的注册并且开始 JMS连接。 因为 JMS定义了一个标准,一个基于 JNDI的机制,用于获得 JMS主题,队列,连接以及一个能够使用任何JMS供应商实现的高端的应用程序服务器的引用。 这允许设计者在开发商业程序时最充分的利用应用程序服务器和JMS服务器。

上一页  1 2 3 4 5 6  下一页

【责任编辑:方舟】
【发表评论】【关闭窗口】
■ 相关内容
 通过JDBC连接oracle数据库的十大技巧
 用JAVA实现线程等待提示框
 优化Java applets 加载过程
 爪哇语言简单工厂创立性模式介绍
 爪哇语言单态创立性模式介绍
 利用Socket进行Java网络编程
 雅加达蚂蚁:新一代Java产品生成器
 开发完整J2EE解决方案的八个步骤
 使用UML编写Java应用程序
 利用数字签名超越Java Applet的安全限制
 移动通讯软件开发平台MIDP编程
感谢 访问天极网,如果您觉得该文章涉及版权问题,请看这里!