作者:自由的猪 制作整理:左岸网络http://www.leftworld.net |
||||||||||
|
第7章一个消息驱动Bean的例子 Dale Green,Kim Haase著 Iceshape Zeng译 因为消息驱动Bean建立在Java消息服务(Java Message Service,JMS)技术的基础上,所以在学习本章之前,你应该已经熟悉了如消息和消息服务等的JMS概念。你可以通过Java Message Tutorial来学习JMS,在以下网址可以找到这本书: http://java.sun.com/products/jms/tutorial/index.html 本章讨论一个消息驱动Bean的例子,如果你没有读过第3章的什么是消息驱动Bean一节,那么再回头看一下这些基础概念。 本章内容: 例子应用程序介绍 J2EE应用程序客户端 消息驱动Bean类 onMessage方法 ejbCreate和ejbRemove方法 运行该例子 启动J2EE服务器 创建消息队列 部署该应用程序 运行客户端 用deploytool部署消息驱动Bean 指定Bean类型和事务处理机制 配置消息驱动Bean的特有属性 用deploytool配置JMS客户端 配置资源引用 配置资源环境引用 设置JNDI名 这各应用程序有两个组成部分(消息驱动Bean没有本地和远程接口): ☆ SimpleMessageClient:向消息队列发送消息的J2EE应用程序客户端 ☆ SimpleMessageEJB:异步接收并处理消息队列中消息的消息驱动Bean 图7-1显示了这各应用程序的结构。客户端发送消息到消息队列,该消息队列是用j2eeadmin命令创建的。JMS服务提供者(这里是J2EE服务器)将消息传送给消息驱动Bean实例处理。
图 7-1 SimpleMessageApp结构 这个程序的源文件放在 二.J2EE应用程序客户端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("This is message " + (i + 1)); System.out.println("Sending message: " + message.getText()); queueSender.send(message); } 参照SimpleMessageEJB类我们先看一下消息驱动Bean类的要求: ☆ 实现MessageDrivenBean和MessageListener接口 ☆ 定义为公有(public)类 ☆ 不能定义成abstract和final类 ☆ 实现onMessage方法 ☆ 实现ejbCreate和ejbRemove方法 ☆ 必须有一个无参构造函数 ☆ 不能定义finalize方法 和会话Bean和实体Bean不同,消息驱动Bean没有本地接口和远程接口。客户端不必查找消息驱动Bean的实例,并在这些接口上调用方法。虽然消息驱动Bean也没有商业方法,但是它可以有辅助类并在onMessage方法例调用这些辅助类的方法。 OnMessage方法 当消息队列收到一条消息,EJB容器调用消息驱动Bean的onMessage方法。在SimpleMessageBean类中,onMessage方法将接收到的消息恢复造型为TextMessage消息并显示消息内容: public void onMessage(Message inMessage) { TextMessage msg = null; try { if (inMessage instanceof TextMessage) { msg = (TextMessage) inMessage; System.out.println ("MESSAGE BEAN: Message received: " + msg.getText()); } else { System.out.println ("Message of wrong type: " + inMessage.getClass().getName()); } } catch (JMSException e) { e.printStackTrace(); mdc.setRollbackOnly(); } catch (Throwable te) { te.printStackTrace(); } } ejbCreate和ejbRemove方法 这两个方法签名的规则: ☆ 必须是公有(public)方法 ☆ 返回类型是void ☆ 不能是abstract和final方法 ☆ 不能有throws子句 ☆ 没有参数 本例SimpleMessageBean类中ejbCreate和ejbRemove方法都是空方法。 四.运行本例子启动J2EE服务器 在命令模式下执行如下命令: j2ee –verbose 创建消息队列 1.创建: 2eeadmin -addJmsDestination jms/MyQueue queue 2.确认消息队列已经创建: j2eeadmin -listJmsDestination 部署该程序 1.在deploytool工具中打开SimleMessageApp.ear文件 2.部署。注意确认在Introduction对话框中选中Return Client JAR复选框 运行客户端 1.在命令模式下进入 2.设置环境变量APPCPATH为SimpleMessageAppClient.jar所在目录 3.运行客户端: runclient -client SimpleMessageApp.ear -name SimpleMessageClient -textauth 4.在登陆提示符后输入用户名:j2ee,密码:j2ee 5.客户端显示结果: Sending message: This is message 1 Sending message: This is message 2 Sending message: This is message 3 6.J2EE服务器终端(启动J2EE服务器的命令窗口)输出的信息: MESSAGE BEAN: Message received: This is message 1 MESSAGE BEAN: Message received: This is message 2 MESSAGE BEAN: Message received: This is message 3 本章介绍部署消息驱动Bean和第2章部署企业Bean基础步骤的不同。 指定Bean类型和事务管理机制 打开新建企业Bean向导,创建消息驱动Bean(类文件加入都一样) 1.在General对话框中,选中Message-Dirven单选按钮 2.在Transaction Management对话框指定事务管理机制。可以是容器管理(Container-Managed)和Bean管理(Bean-Managed)中的任意一个。不过选择Bean管理的事务时,在第4不中就要指定应答(Acknowledgement)类型。 设置消息驱动Bean的特有属性 你可以在两个地方设置这些属性: 1.上面提到的新建企业Bean向导的第4步 2.消息驱动Bean的Message选项页(如图7-2) 需要设置的属性如下: 1.Desination Type通过两个单选按钮Queue(消息队列)和Topic(消息主题)来设置。消息队列使用点对点消息域,它只能有一个消息消费者。消息主题使用发布-订阅消息域,它可以有0个或多个消息消费者。 2.在Destination下拉框中选择你用j2eeadmin命令创建的消息的JNDI名。目的地(destination)可以是Queue和Topic中的任意类型,它是消息转发服务的提供者(it represents the source of incoming messages and the target of outgoing messages) 3.Connection Factory下拉框,在QueueConnectionFactory和TopicConnectionFactory中选择合适的一个(其实这两个工厂在选择Desination Type就被过滤了一个了)。它们提供J2EE组件访问消息服务的连接。 4.如果你设置的是Bean管理的事务,那么你也要选择应答(Acknowledgment)类型:Auto-Acknowledge或者Duplicates-OK。Auto-Acknowledge指示会话自动应答消息驱动Bean消费了消息。Duplicates-OK指示会话不必确保对发送消息的应答(The Duplicates-OK type instructs the session to lazily acknowledge the delivery of messages),它可能引起消息重复,但是降低了会话费用。 5.在JMS Message Selector域中,你可定义过滤收到消息的语句。
图 7-2 SimpleMessageEJB的Message页 六.用deploytool配置JMS客户端本节只是简要介绍JMS客户端的配置,要知道更多信息请参考Java Message Service Tutorail。 配置资源引用 1.在树视图中选中客户端节点 2.选择Resource Refs选项页 3.点击Add按钮 4.在Coded Name列输入和客户端调用lookup方法时用的参数对应的名字(当然你也可以在这里先设置了之后,再写客户端的lookup调用)。如本例客户端lookup方法调用的参数是 5.在Type列选择和消息目的地(destination)类型一致的连接工厂类 6.在Authentication列,大部分时候你应该选择Container。如果在程序中编码登录消息服务,你可以选择Application。 7.在Sharable列中,确信复选框被选中。这样可以让容器优化连接。 8.在User Name和Password域输入用户名和密码。J2EE SDK的验证服务将在客户端运行时提示你输入用户名和密码。 配置资源环境引用 1.选择Resource Env. Refs选项页 2.点击Add按钮 3.在Coded Name列输入和调用lookup方法定位消息队列或者消息主题时的参数一致的名字。本例中lookup方法调用的参数为: 4.在Type列选择和目的地类型一致的类型(一般工具会自动选择一个正确的类型) 设置JNDI名 1.在树视图中选择应用程序节点 2.选择JNDI Name选项页,设置用到资源的正确JNDI名。表7-1列出了本例中使用的JNDI:
| ||||||||||