Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->系统管理 ->正文

全面研读 EJB 2.0

来源:Linux-cn.com 作者:Webmaster 时间:2007-05-05 点击: [收藏] [投稿]

  EJB 2.0 中的 JMS

  EJB 2.0 以两种方式支持 JMS 的集成:作为一种 bean 可用的资源,和作为一个MessageDrivenBean。当将 JMS 用作一种资源时,使用 JMS API 的 bean就是消息的产生者或发送者。在这种情况下,bean将消息发送给称为主题或队列的虚拟通道。另一方面,MessageDrivenBean 则是消息的使用者或接收者。它监听特定的虚拟通道(主题或队列),并处理发送给该通道的消息。为了更好地理解消息产生者和消息使用者的作用,用 SessionBean bean 来发送一条使用 JMS 的消息,然后使用一个新的MessageDrivenBean 来使用该同一条消息。

  作为 EJB 2.0 资源的 JMS

  会话 bean 和实体 bean 都是基于 RPC 的组件,为了将各种事务性的组件装配到一起,这是一种卓越的体系结构。但是,在某些情况下,RPC的同步性质会成为一种障碍,这正是 EJB 1.1 中将对 JMS API 的访问作为一种资源包括在内的原因。利用 JNDI环境命名的上下文,bean 可以获得一个 JMS 工厂,并将一条异步消息发送给主题或队列(也从 JNDI 获得),而不必等待回应。下面是 ShoppingCart bean的一个例子,它使用 JMS 将 Order 的详细信息发送给消息收发主题。


public class ShoppingCartBean implements SessionBean {
   // 订单详细信息是一个可序列化的对象,它包含全部订单信息。
   public OrderDetail orderDetail;
    public void processOrder(){
          // 处理订单的逻辑从此处开始
....
          // ... 处理订单以后,向其它系统发送有关此订单的一条消息
          InitialContext jndiEnc = new
InitialContext();
          // 使用 JNDI ENC 获取 JMS 工厂和主题标识符
          TopicConnectionFactory factory =
          jndiEnc.lookup("java:comp/env/jms/topicfactory");
          Topic orderTopic =
jndiEnc.lookup("java:comp/env/jms/ordertopic");
          // 获得一个用来发送消息的发布者
          TopicConnection con =
factory.createTopicConnection();
          TopicSession session =
                   con.createTopicSession(false,
Session.AUTO_ACKNOWLEDGE );
          TopicPublisher publisher =
session.createPublisher(orderTopic);
          // 将一个 ObjectMessage 发送给主题(虚拟通道)
          ObjectMessage message =
session.createObjectMessage();
          message.setObject(orderDetail);
          publisher.publish(message);
          con.close();
    }
    ...
}

  在这种情况下,JMS 是用来通知另外的应用程序,订单已被处理。这些另外的应用程序对于处理订单来说并不重要,但它们会因为得到一个订单已被处理的通知而受益。这样的例子包括自动调整库存的库存系统,和能将客户添加进产品目录邮寄名单中的销售应用程序。

  使用 JMS 使 bean 能够发布(发送)消息而不会发生阻塞。bean 并不知道谁将收到消息,因为它是将消息发送给某个主题(虚拟通道),而不是直接发送给另一个应用程序。应用程序可以选择预订该主题,并接收有关新订单的通知。这样就有可能动态地在虚拟通道中添加或删除应用程序,从而产生了一种更加灵活的系统。

  预订了订单主题的应用程序将收到有关新订单的通知,应用程序可以使用它们认为合适的任何方式来处理这个通知。预订了各种主题的应用程序或者从各个队列中接收消息的应用程序可以是 Java 应用程序、EAI 系统(用于集成遗留系统和 ERP 系统)或者MessageDrivenBean 组件,在 JMS 的术语中,它们全部被认为是 JMS 客户机。

  JMS 和 MessageDrivenBean

  虽然大多数 JMS 厂商都提供消息中介工具,来将消息从发送者路由到接收者,但构建使用(接收)消息的 JMS 客户机却是应用程序开发人员的职责。在许多情况下,接收消息的应用程序必须强健、安全、快速而且可伸缩;它需要的基础结构基本上与 EJB应用程序相同。

  由于认识到这种需要,EJB 2.0 现在包括了 MessageDrivenBean 类型,它可以使用JMS消息,并且在同一个强健的、基于组件的基础结构中处理这些消息,这样的基础结构对于会话 bean 和实体 bean 都非常有用。MessageDrivenBean 类型(消息bean)是一种企业级 bean 组件,它设计来使用异步的 JMS 消息。

  除了提供容器基础结构以外,EJB 还具有另一个重要的优点:并发处理。在 EJB中,一个已部署的消息 bean 表示一个单一的消息使用者,但这个 bean 本身是由许多bean 实例提供服务的。每个 bean 实例都可以分别地使用消息 bean接收到的消息。这意味着,消息 bean 不必像常规 JMS 客户机那样连续地使用消息。消息 bean 可以并发地使用接收到的多个消息,这样就能达到比传统 JMS 应用程序高得多吞吐量和好得多的可伸缩性。

  为了说明消息 bean 的作用,就开发了 MarketingBean 类,并将它从订单主题中部署到供使用的消息中去。MarketingBean 将从消息中提取 OrderDetail对象,并使用它将客户添加到适当的目录邮寄名单中。这是一种最精致的大量邮寄系统。下面是 MarketingBean 类的定义,这个类使用发布给订单主题的消息。


public class MarketingBean implements
javax.ejb.MessageDrivenBean {
      public void onMessage(Message message) {
          ObjectMessage orderMessage =
(ObjectMessage)orderMessage:
            OrderDetail orderDetail =
(OrderDetail)orderMessage.getObject();
          Integer customerID =
orderDetail.getCustomerID();
          InitialContext jndiEnc = new
InitialContext();
          CatalogHome catalogHome =
            (CatalogHome)jndiEnc.lookup("java:comp/env/ejb/catalog");
          Iterator productIDs =
orderDetail.getProductsIDs();
          while(productIDs.hasNext()){
            Integer productID =
(Integer)productIDs.next();
            Catalog cat =
CatalogHome.findByProductID(productID);
            cat.addCustomerToMailingList(customerID);
          }
     }
}


 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



上一篇:Enterprise JavaBeans简介   下一篇:Java 2 EE开发指南(二)

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章