标签:
消息驱动bean的主要用于接受和处理异步消息,这些信息可能来自一个外部的系统或者同一个应用中的其它组件,之所以称它们为异步,那时因为这些消息可以在任何时候到达,而不同于一般的远程方法调用的结果,是立马直接得到的。同UI的事件处理工作方式类似,消息驱动bean用于监听发送给它的异步消息。值得注意的是,与远程调用方法不同,异步消息的发送者不会停下来去等待对方的响应。
消息驱动bean是J2EE中的一个标准服务(工具),全称是Java Message Service API,简称为JMS。Java Message Service API是一个Java API,位于javax.jms包中,它为所有需要消息系统服务的应用提供了一个接口。消息系统能够异步的发送和接受消息,这些消息可以是文本、对象或者其它的一些类型。这与远程过程调用(RPC)模型是相反的,在远程过程调用中,组件之间的交互都是同步发生的。任何一个符合JMS API规范的消息系统的实现都可以称做是一个JMS提供者(JMS Provider)。在J2EE SDK中自带有这个的一个JMS Provider,书中的例子也是使用的这个JMS Provider,各个供应商也有自己的商业实现用于在企业级应用中使用消费服务。书中给出的JMS例子的上下文可以用下图来表示:
在上图中,TimeIt是一个会话bean,它的主要作用就是向MessageWriter这个消息驱动bean发送异步消息,TimeIt和MessageWriter这两个企业bean可以称之为JMS Clients,因为它们都是底层消息系统的客户端。消息系统通过提供一个目的地(destination)存放消息直至这些消息被发送至接收方(recipient)来实现异步通信。上图中间的LogWriterQueue就是一个这样的目的地,它保存了所有来自TimeIt会话bean的消息,这些消息都将发往MessageWriter消息驱动bean。在JMS中有两种类型的目的地(destination):
● 队列(Queue),用于保存从一个JMS客户端发往另一个JMS客户端的消息,这种消息模型被称为点对点(point-to-point);
● 主题(Topic),用于保存从许多潜在的JMS客户端发往多个潜在的JMS客户端的消息,这种消息模型被称为发布/订阅(publish/subscribe)模式;
书中的例子所使用是的Queue类型的目的地。在上图中还有两个“角色”:JMS消息制造者和JMS消息消费者,它们是JMS提供者里面代表JMS客户端去发送和接收消息的类。当我们使用消息驱动bean时,不必自己去创建一个JMS消息消费者,因为EJB容器会替我们做这些事情,但是JMS消息制造者就需要我们自己去创建了,我们需要创建一个JMS消息制造者向目的地(可能是Queue也可能是Topic,书中例子是Queue,即上图中的LogWriterQueue)发送消息。为了实现这个功能,我们需要两个管理对象(administered object),它们通常是由JMS提供者所带的管理工具所管理的,这两个管理对象分别是:
● 连接工厂(connection factory),用于创建一个到JMS提供者的连接
● 目的地(destination),可以是javax.jsm.Queue和javax.jsm.Topic类型
一个典型的发送消息的过程如下所示:
//第一步,得到连接工厂,书中例子因为使用的Queue类型目的地,所示这里使用的
QueueConnectionFactory,其中XXXXX是部署时所设置的jndi名
InitialContext jndiContext = new InitialContext();
QueueConnectionFactory queueConnectionFactory =
(QueueConnectionFactory) jndiContext.lookup(“XXXX”)
//第二步,得到目的地,书中例子使用的Queue,XXXXX也是部署时设置的JNDI名
Queue queue = (Queue) jndiContext.lookup("XXXXX");
//第三步,从连接工厂中获得一个连接
queueConnection =queueConnectionFactory.createQueueConnection();
//第四步,创建一个会话
QueueSession queueSession =
queueConnection.createQueueSession(false,
Session.AUTO_ACKNOWLEDGE);
//第五步,为当前会话创建一个发往Queue的发送者
QueueSender queueSender = queueSession.createSender(queue);
//第六步,创建一个消息
TextMessage message = queueSession.createTextMessage();
SimpleDateFormat sdf =new SimpleDateFormat("yyyy.MM.dd ‘at‘ HH:mm:ss.SSS");
message.setText("log entry, the time is: " + sdf.format(new Date()));
//第七步,发送消息
queueSender.send(message);
//第八步,关闭连接
queueConnection.close();
在消息驱动bean中处理收到异步消息后所执行的动作,一个消息驱动bean必须继承两个接口,它们是:
● MessageDirvenBean:包含了消息驱动bean的生命周期方法
● MessageListener:包含onMessage()方法,当有一条消息到达消息驱动bean时这个方法会被调用。
标签:
原文地址:http://my.oschina.net/moziqi/blog/363307