1。首先配置jboss的jbossmq,启动jboss(启动jboss时会同时启动mq,使用其他mq时类似,需要配置启动mq)
2。在spring中进行消息发送接收者的相关配置(封装了jms发送与接收的模版)
<!-- jndi配置 -->
<bean id="jndiTemplate"
class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">
org.jnp.interfaces.NamingContextFactory
</prop>
<prop key="java.naming.provider.url">172.16.13.79</prop>
<prop key="java.naming.factory.url.pkgs">
org.jnp.interfaces:org.jboss.naming
</prop>
</props>
</property>
</bean>
<!-- jms连接工厂配置 -->
<bean id="jmsConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>ConnectionFactory</value>
</property>
</bean>
<!-- 目标队列配置 -->
<bean id="destination"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="jndiTemplate" />
</property>
<property name="jndiName">
<value>queue/A</value>
</property>
</bean>
<!-- 生产者配置 -->
<bean id="messageProducer"
class="com.xhb.test.jms.MessageProducer">
<property name="template" ref="jmsQueueTemplate" />
<property name="destination" ref="destination" />
</bean>
<!-- jms模版 -->
<bean id="jmsQueueTemplate"
class="org.springframework.jms.core.JmsTemplate102">
<property name="connectionFactory">
<ref bean="jmsConnectionFactory" />
</property>
<property name="defaultDestination" ref="destination" />
<property name="pubSubDomain">
<value>false</value>
</property>
<property name="receiveTimeout">
<value>20000</value>
</property>
</bean>
<!-- 监听器 -->
<bean id="messageListener"
class="com.xhb.test.jms.MessageConsumer">
</bean>
<!-- 监听器容器 -->
<bean id="listenerContainer"
class="org.springframework.jms.listener.DefaultMessageListenerContainer">
<property name="connectionFactory" ref="jmsConnectionFactory" />
<property name="destination" ref="destination" />
<property name="messageListener" ref="messageListener" />
</bean>
3。原生使用的jms方式如下
(1) 得到一个JNDI初始化上下文(Context);
例子对应代码:
Properties props = new Properties();
props.setProperty("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
props.setProperty("java.naming.provider.url", "localhost:1099");
props.setProperty("java.naming.factory.url.pkgs", "org.jboss.naming");
InitialContext ctx = new InitialContext(props);
注意:可以写在代码中,也可以写在jndi.properties文件中.
(2) 根据上下文来查找一个连接工厂TopicConnectFactory/ QueueConnectionFactory (有两种连接工厂,根据是topic/queue来使用相应的类型);
例子对应代码:
QueueConnectionFactory qcf =(QueueConnectionFactory) ctx.lookup("ConnectionFactory");
(3) 从连接工厂得到一个连接(Connect 有两种[TopicConnection/ QueueConnection]);
例子对应代码:conn = qcf.createQueueConnection();
(4) 通过连接来建立一个会话(Session);
例子对应代码:session= conn.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE);
这句代码意思是:建立不需要事务的并且能自动接收Java消息服务收条的会话,在非事务Session 中,JMS消息传递的方式有三种:
Session.AUTO_ACKNOWLEDGE :当客户机调用的receive方法成功返回,或当MessageListenser 成功处理了消息,session将会自动接收消息的收条。
Session.CLIENT_ACKNOWLEDGE :客户机通过调用消息的acknowledge方法来接收消息。接收发生在session层。接收到一个被消费的消息时,将自动接收该session已经 消费的所有消息。例如:如果消息的消费者消费了10条消息,然后接收15 个被传递的消息,则前面的10 个消息的收据都会在这15 个消息中被接收。
Session.DUPS_ACKNOWLEDGE :指示session缓慢接收消息。
session是一个非常核心的概念,在一次session(会话中)可以发送消息,也可以消费消息,消费消息时既可以主动去消费也可以设置针对消息队列的监听,被动触发处理,设置监听示例如下。
QueueReceiver reciver = session.createReceiver(queue);
reciver.setMessageListener(listener);
(5) 查找目的地(Topic/ Queue);
例子对应代码:queue =(Queue) ctx.lookup("queue/jms");
(6) 根据会话以及目的地来建立消息制造者(TopicPublisher/QueueSender)和消费者(TopicSubscriber/QueueReceiver).
例子对应代码:
msg = session.createTextMessage("你好,好久不见!");
sender = session.createSender(queue);
sender.send(msg);