概念:
1.java消息驱动bean属于Java消息服务(Java Message Service,简称JMS)。
2.JMS是用于访问企业消息系统的开发商中心的API。企业消息系统可以协助应用软件通过网络进行消息交互。
3.JMS的编程过程简单概括为:应用程序A-->(消息)-->Jboss JMS-->(消息)-->应用程序B。应用程序A和应用程序B没有直接的代码关联,两者实现了解耦。消息传递系统的中心就是消息。
消息驱动Bean(MDB)是设计用来专门处理基于消息请求的组件,它和无状态Session Bean一样也使用了实例池技术,容器可以使用一定数量的bean实例并发处理成百上千个JMS消息。正因为MDB具有处理大量并发消息的能力,所以非常适合应用在一些消息网关产品。如果一个业务执行的时间很长,而执行结果无需实时向用户反馈时,也很适合使用MDB。如订单成功后给用户发送一封电子邮件或发送一条短信等。
消息有下面几种类型,他们都是派生自Message接口。
StreamMessage:一种主体中包含Java基本值流的消息。其填充和读取均按顺序进行。
MapMessage:一种主体中包含一组名-值对的消息。(没有定义条目顺序)
TextMessage:一种主体中包含Java字符串的消息(例如:XML消息)
ObjectMessage:一种主体中包含序列化Java对象的消息。
BytesMessage:一种主体中包含连续字节流的消息。
消息的传递模型:
JMS支持两种消息传递模型:点对点(point-to-point,简称PTP)和发布/订阅(publish/subscribe,简称pub/sub)。
二者有以下区别:
1.PTP 消息传递模型规定了一条消息只能传递给一个接收方。采用javax.jms.Queue表示。
2.Pub/sub 消息传递模型允许一条消息传递给多个接收方。采用javax.jms.Topic表示。
注意:每种模型都通过扩展公用基类来实现。例如,javax.jms.Queue 和javax.jms.Topic都扩展自javax.jms.Destination 类。
Queue类型消息开发步骤:
1.首先配置一个Queue类型的目标地址,放在JBOSS目录下的D:\jboss-4.2.3.GA\server\default\deploy,
名字必须叫 *-server.xml
<?xml version="1.0" encoding="UTF-8"?> <server> <mbean code="org.jboss.mq.server.jmx.Queue" name="jboss.mq.destination:service=Queue,name=itcastQueue"> <attribute name="JNDIName">queue/itcastQueue</attribute> <depends optional-attribute-name="DestinationManager">jboss.mq:service=DestinationManager</depends> </mbean> </server>
在控制台 http://localhost:7070/jmx-console/ 找到 jboss.mq.destination ,以看到我们设置的queue类型的目标地址
2.java 中发送消息的概括
1.得到一个JNDI初始化上下文(Context)
InitialContext ctx = new InitialContext();
2.根据上下文查找一个连接工厂ConnectionFactory,改连接工厂是由JMS提供的,不需我们自己创建,每个厂商都为它绑定了一个全局JNDI,我们通过它的全局JNDI便获取它;
QueueConnectionFactory factory = (QueueConnectionFactory)ctx.lookup("ConnectionFactory");
3.从连接工厂得到一个连接QueueConnection。
QueueConnection conn = factory.createQueueConnection();
4.通过连接来建立一个会话(Session);
QueueSession session = conn.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE);
这句代码意思是:建立不需要事务的并且能自动确立消息已接收的会话。
5.查找目标地址:
Destination destination=(Destination)ctx.lookup("queue/ztfQueue");
6.根据会话以及目标地址来建立消息生产者MessageProducer(QueueSender和TopicPublisher都扩展自MessageProducer接口):
MessageProducer producer = session.createProducer(destination);
TextMessage msg = session.createTextMessage("您好:胡晓亮,这是我的第一个消息驱动Bean");
producer.send(msg);
3.建立一个java项目,把jboss的client目录下的jar包全部buildPath到编译路径中
4.写消息的发送端
package cn.com.xinli.jms.app; import javax.jms.Destination; import javax.jms.MessageProducer; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueSession; import javax.jms.TextMessage; import javax.naming.InitialContext; public class QueueSender { /** * 消息发送端 */ public static void main(String[] args) { try { /*需要从jndi.properties中读取上下文信息*/ InitialContext ctx = new InitialContext(); QueueConnectionFactory factory = (QueueConnectionFactory)ctx.lookup("QueueConnectionFactory"); QueueConnection conn = factory.createQueueConnection(); QueueSession session = conn.createQueueSession(false,QueueSession.AUTO_ACKNOWLEDGE); Destination destination=(Destination)ctx.lookup("queue/itcastQueue"); MessageProducer producer = session.createProducer(destination); TextMessage msg = session.createTextMessage("您2好:胡晓亮,这是我的第一个消息驱动Bean"); producer.send(msg); session.close(); conn.close(); System.out.println("消息发送成功"); } catch(Exception e) { System.out.println("消息发送失败"); e.printStackTrace(); } } }
jndi.properties
java.naming.provider.url = localhost:1099 java.naming.factory.initial = org.jnp.interfaces.NamingContextFactory
5.写消息的接收端
采用MessageDrivenBean接收消息。
当容器检测到bean守候的目标地址有消息到达时,容器调用onMessage()方法,将消息作为参数传入MDB。MDB在onMessage()中决定如何处理改消息。你可以使用注解指定MDB监听哪一个目标地址(Destination)。当MDB部署时,容器将读取其中的配置信息。
一个MDB通常要实现MessageListener接口,在接口定义了onMessage()方法。Bean通过它来处理收到的JMS消息。
package cn.com.xinli.jms.app; import javax.ejb.MessageDriven; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.MessageListener; import javax.jms.TextMessage; import javax.ejb.ActivationConfigProperty; @MessageDriven(activationConfig= { @ActivationConfigProperty(propertyName="destinationType",propertyValue="javax.jms.Queue"), @ActivationConfigProperty(propertyName="destination",propertyValue="queue/itcastQueue"), @ActivationConfigProperty(propertyName="acknowledgeMode",propertyValue="Auto-acknowledge") }) public class MessageDriverBean implements MessageListener { public void onMessage(Message msg) { TextMessage message = (TextMessage)msg; try { System.out.println("接收到消息:"+message.getText()); } catch (JMSException e) { e.printStackTrace(); } } }
6.打包部署:讲项目打成一个jar包,貌似netbC.jar,放在JBOSS的deploy目录下,启动jboss
7.运行QueueSender.java 发送消息
8.Jboss中看到
10:21:33,984 INFO [STDOUT] 接收到消息:您好:胡晓亮,这是我的第一个消息驱动Bean