技术开发 频道

J2EE组件开发:消息驱动的EJB


四、发布-订阅消息模式
 
  在一个支持发布-订阅消息模式的系统中JMS的基本体系结构。发布-订阅消息机制也是核心JMS机制的一种扩展,增加了一些适合发布-订阅消息模式的功能。连接工厂、连接、会话、消息生产者、消息消费者等都用发布-订阅形式的接口进行了扩展。
 
  JMS客户程序通过JNDI获得一个TopicConnectionFactory对象的引用。TopicConnectionFactory.createTopicConnection()方法用来创建TopicConnection对象的实例。调用createTopicConnection()方法时可以指定一个用户名字和密码,或者,我们也可以使用该方法不带参数的版本,此时假定使用默认用户身份。
 
  TopicConnection接口是Connection接口的一种子类型,它代表着一个与JMS发布-订阅消息服务的连接。JMS客户程序调用TopicConnection.createTopicSession()方法创建Top icSession的实例。会话的事务支持和回执模式也在创建TopicSession时指定。
 
  TopicSession.createTopic()方法返回一个Topic对象的实例。Topic接口封装了一个话题目的地,发布者向该目的地发送消息,订阅者从该目的地接收消息。不同的服务提供者按照不同的方式实现话题名称的层次结构,调用Topic.getTopicName()方法可以获得话题的String形式的描述。
 
  TopicSession.createPublisher()方法创建一个TopicPublisher消息生产者,它用来把消息发布到Topic。消息可以通过各种不同的TopicPublisher.publish()方法发布到Topic,这些不同的publish()方法能够把消息发送给TopicPublisher对象关联的Topic对象,或者发送给publish()方法调用中指定的Topic对象。消息递送模式、优先级、消息的有效时间都可以在调用TopicPublisher.publish()方法时指定。发送给Topic的消息可以用Session接口中定义的各种消息构造方法创建。
 
五、实例
 
  本示例应用是一个消息驱动Bean应用的简单例子,由以下两部分构成:
 
  SimpleMessageClient:J2EE应用客户程序,向队列发送消息。
 
  SimpleMessageEJB:一个消息驱动的Bean,异步地接收和处理由客户程序发送到队列的消息。
 
  客户端应用把消息发送到队列,队列由管理员通过j2eeadmin命令创建。JMS提供者(这里是J2EE服务器)把消息传递给消息驱动Bean的实例,由Bean的实例处理消息。
 
5.1 客户端
 
SimpleMessageClient把消息发送到SimpleMessageBean监听的队列。客户程序首先确定连接工厂和队列:
 
queueConnectionFactory = (QueueConnectionFactory) jndiContext.lookup
 
("java:comp/env/jms/MyQueueConnectionFactory");
 
queue = (Queue) jndiContext.lookup("java:comp/env/jms/QueueName");
 
接下来,客户程序创建队列连接、会话和一个消息发送器:
 
queueConnection = queueConnectionFactory.createQueueConnection();
 
queueSession = queueConnection.createQueueSession(false,
 
Session.AUTO_ACKNOWLEDGE);
 
queueSender = queueSession.createSender(queue);
 
最后,客户程序把几个消息发送到队列:
 
message = queueSession.createTextMessage();
 
for (int i = 0; i < NUM_MSGS; i++) {
 
message.setText("我是" + msgArray[i] );
 
System.out.println("Sending message: " +
 
message.getText());
 
queueSender.send(message);
 
}
 
5.2 MDB组件
 
SimpleMessageEJB类阐明了编写消息驱动Bean类的要求:
 
实现MessageDrivenBean接口和MessageListener接口。
 
类定义为public类型。
 
类不能定义成abstract或final。
 
实现一个onMessage()方法。
 
实现一个ejbCreate()方法和一个ejbRemove()方法。
 
包含一个public类型的不需要参数的构造方法。
 
不能定义finalize()方法。
 
  与会话Bean和实体Bean不同,消息驱动的Bean不定义客户程序访问的接口。客户程序不是先定位消息驱动的Bean,再调用这些Bean上的方法。虽然消息驱动的Bean没有业务方法,但它们可以包含由onMessasge()方法内部调用的辅助方法。
 
  当队列接收到一个消息,EJB容器将调用消息驱动Bean的onMessage()方法。在SimpleMessageBean类中,onMessage()方法把接收到的消息定型(cast)成为TextMessage类型,然后显示出文本信息:
 
public void onMessage(Message inMessage) {
 
TextMessage msg = null;
 
try {
 
if (inMessage instanceof TextMessage) {
 
msg = (TextMessage) inMessage;
 
System.out.println("MESSAGE BEAN:收到消息: "
 
+ msg.getText());
 
} else {
 
System.out.println("消息类型错误: "
 
+ inMessage.getClass().getName());
 
}
 
} catch (JMSException e) {
 
e.printStackTrace();
 
mdc.setRollbackOnly();
 
} catch (Throwable te) {
 
te.printStackTrace();
 
}
 
}
 
消息驱动Bean的ejbCreate()方法和ejbRemove()方法必须符合以下要求:
 
访问控制修饰符必须是public。
 
返回值类型必须是void。
 
不能有static和final修饰符。
 
throws子句不能定义任何应用自定义的异常。
 
不能带有参数。
 
在SimpleMessageBean类中,ejbCreate()方法和ejbRemove()方法都是空的,不执行任何
 
有实际意义的操作。
 
5.3 打包
 
  接下来我们要把上面的应用打包成一个J2EE EAR文件。首先要把SimpleMessageEJB打包成Jar文件。通常,打包过程可以通过工具完成,但理解模块部署描述器仍是必要的。在EJB应用模块部署描述器中,优异元素下面包含元素。下面可以包含一组元素(按照EJB 2.0新规范),每一个元素描述一个消息驱动Bean的配置和部署。SimpleMessageEJB的ejb-jar.xml文件如下所示。元素内定义了消息驱动Bean的配置和部署信息,例如唯一的Bean名字、Bean类的名字、配置参数、安全信息、事务信息、消息目的地类型等。
 
......
SimpleMessageJAR
SimpleMessageEJB
SimpleMessageEJB
SimpleMessageBean
Container
javax.jms.Queue
SimpleMessageEJB
Bean
onMessage
javax.jms.Message
Required
 
  除了ejb-jar.xml部署描述器之外,通常还要有面向特定平台和环境的部署描述器。大多数时候,这种描述器可以用GUI工具编写。请参见下载代码中提供的例子。
 
  打包好各个模块之后,接着还要把J2EE应用打包成EAR文件。有关这一步骤的详细说明,请参见开发平台的相关文档。本文以后有关部署和运行的说明,就以打包后的EAR文件为基础。
 
5.4 部署和运行
 
假设我们在Sun的J2EE参考实现上部署和测试这个示例应用。为便于查看消息驱动Bean的输出,我们必须以-verbose模式启动服务器:
 
j2ee -verbose
 
用下面的j2eeadmin命令创建队列:
 
j2eeadmin -addJmsDestination jms/MyQueue queue
 
验证队列已经创建成功:
 
j2eeadmin -listJmsDestination
 
启动deploytool,选择菜单File-->Open,打开SimpleMessageApp.ear文件。接着,选择菜单Tools --> Deploy,部署应用。出现部署提示时,选中Return Client JAR检查框。
 
在一个命令窗口中,进入EAR文件(SimpleMessageAppClient.jar文件)所在目录,把环境变量APPCPATH设置为SimpleMessageAppClient.jar。然后,执行下面的命令:
 
runclient -client SimpleMessageApp.ear -name SimpleMessageClient -textauth
 
在登录提示中,输入用户名字j2ee,输入密码j2ee。此时,客户程序将输出以下内容:
 
Sending message: 我是老大孙悟空
 
Sending message: 我是老二猪八戒
 
Sending message: 我是老三沙和尚
0
相关文章