简介
 实战一 , 实战二介绍了ActiveMQ的基本概念和配置方式.
 本篇将通过一个实例介绍使用spring发送,消费topic, queue类型消息的方法. 不懂topic和queue的google 之.
   
 如图示, TOPIC和QUEUE分别代表一个topic和一个queue消息通道.
- TopicMessageProducer向topic发送消息, TopicConsumerA和TopicConsumerB则从topic消费消息.
- QueueMessageProducer向Queue发送消息, QueueConsumer从Queue中消费消息
Spring整合JMS
 就像对orm, web的支持一样, spring同样支持jms, 为整合jms到已有的项目提供了很多便利的方法. 本篇主要讲实战, 是所以先从配置开始, spring配置jms基本上需要8个部分.
- ConnectionFactory. 和jms服务器的连接, 可以是外部的jms server, 也可以使用embedded ActiveMQ Broker.
- Destination. 有topic和queue两种方式.
- JmsTemplate. spring提供的jms模板.
- MessageConverter. 消息转换器.
- MessageProducer. 消息生产者.
- MessageConsumer. 消息消费者.
- MessageListener. 消息监听器
- MessageListenerContainer. 消息监听容器
 下面以实例的方式介绍上面8个部分.
 1. ConnectionFactory
-  <amq:connectionFactory id=“jmsConnectionFactory” brokerURL=“vm://localhost” /> 
 
-  <amq:connectionFactory id=“jmsConnectionFactory” brokerURL=“vm://localhost” />  
 
 brokerURL是指要连接的activeMQ server的地址, activeMQ提供了多种brokerURL, 集体可参见文档.一般我们使用嵌套的ActiveMQ server. 配置如下, 这个配置使用消息的存储机制, 服务器重启也不会丢失消息.
-   
-      <amq:broker useJmx=“false” persistent=“true”> 
-          <amq:persistenceAdapter> 
-              <amq:amqPersistenceAdapter directory=“d:/amq”/> 
-          </amq:persistenceAdapter> 
-          <amq:transportConnectors> 
-              <amq:transportConnector uri=“tcp://localhost:61616” /> 
-                         <amq:transportConnector uri=“vm://localhost:0” /> 
-          </amq:transportConnectors> 
-      </amq:broker> 
 
-    
-  <amq:broker useJmx=“false” persistent=“true”>  
-  <amq:persistenceAdapter>  
-  <amq:amqPersistenceAdapter directory=“d:/amq”/>  
-  </amq:persistenceAdapter>  
-  <amq:transportConnectors>  
-  <amq:transportConnector uri=“tcp://localhost:61616” />  
-  <amq:transportConnector uri=“vm://localhost:0” />  
-  </amq:transportConnectors>  
-  </amq:broker>  
 
 2. Destination
 在实例中我们使用了两种destination
-   
-   
-  <amq:topic name=“TOPIC” physicalName=“JMS-TEST-TOPIC” /> 
-   
-  <amq:queue name=“QUEUE” physicalName=“JMS-TEST-QUEUE” /> 
 
-    
-    
-  <amq:topic name=“TOPIC” physicalName=“JMS-TEST-TOPIC” />  
-    
-  <amq:queue name=“QUEUE” physicalName=“JMS-TEST-QUEUE” />  
 
 3. JmsTemplate
-   
-      <bean id=“jmsTemplate” class=“org.springframework.jms.core.JmsTemplate”> 
-          <property name=“connectionFactory”> 
-               
-              <bean class=“org.springframework.jms.connection.SingleConnectionFactory”> 
-                  <property name=“targetConnectionFactory” ref=“jmsConnectionFactory” /> 
-              </bean> 
-          </property> 
-           
-          <property name=“messageConverter” ref=“defaultMessageConverter” /> 
-      </bean> 
 
-    
-  <bean id=“jmsTemplate” class=“org.springframework.jms.core.JmsTemplate”>  
-  <property name=“connectionFactory”>  
-    
-  <bean class=“org.springframework.jms.connection.SingleConnectionFactory”>  
-  <property name=“targetConnectionFactory” ref=“jmsConnectionFactory” />  
-  </bean>  
-  </property>  
-    
-  <property name=“messageConverter” ref=“defaultMessageConverter” />  
-  </bean>  
 
   4. MessageConverter
    MessageConverter实现的是org.springframework.jms.support.converter.MessageConverter接口, 提供消息的转换功能. DefaultMessageConverter的实现见附件.
-  <bean id=“defaultMessageConverter” class=“com.andyao.activemq.DefaultMessageConverter” /> 
 
-  <bean id=“defaultMessageConverter” class=“com.andyao.activemq.DefaultMessageConverter” />  
 
   5. MessageProducer
    实例拥有两个消息生产者, 消息生产者都是POJO, 实现见附件.
-   
-      <bean id=“topicMessageProducer” class=“com.andyao.activemq.TopicMessageProducer”> 
-          <property name=“template” ref=“jmsTemplate” /> 
-          <property name=“destination” ref=“TOPIC” /> 
-      </bean> 
-      <bean id=“queueMessageProducer” class=“com.andyao.activemq.QueuMessageProducer”> 
-          <property name=“template” ref=“jmsTemplate” /> 
-          <property name=“destination” ref=“QUEUE” /> 
-      </bean> 
 
-    
-  <bean id=“topicMessageProducer” class=“com.andyao.activemq.TopicMessageProducer”>  
-  <property name=“template” ref=“jmsTemplate” />  
-  <property name=“destination” ref=“TOPIC” />  
-  </bean>  
-  <bean id=“queueMessageProducer” class=“com.andyao.activemq.QueuMessageProducer”>  
-  <property name=“template” ref=“jmsTemplate” />  
-  <property name=“destination” ref=“QUEUE” />  
-  </bean>  
 
 6. MessageConsumer
 TOPIC通道有两个消息消费者, QUEUE有一个消息消费者
-   
-       
-      <bean id=“topicConsumerA” class=“com.andyao.activemq.TopicConsumerA” /> 
-       
-      <bean id=“topicConsumerB” class=“com.andyao.activemq.TopicConsumerB” /> 
-       
-      <bean id=“queueConsumer” class=“com.andyao.activemq.QueueConsumer” /> 
 
-    
-    
-  <bean id=“topicConsumerA” class=“com.andyao.activemq.TopicConsumerA” />  
-    
-  <bean id=“topicConsumerB” class=“com.andyao.activemq.TopicConsumerB” />  
-    
-  <bean id=“queueConsumer” class=“com.andyao.activemq.QueueConsumer” />  
 
   7. MessageListener
 每一个消息消费者都对应一个MessageListener
-  <bean id=“topicListenerA” class=“org.springframework.jms.listener.adapter.MessageListenerAdapter”> 
-          <constructor-arg ref=“topicConsumerA” /> 
-           
-          <property name=“defaultListenerMethod” value=“receive” /> 
-           
-          <property name=“messageConverter” ref=“defaultMessageConverter” /> 
-      </bean> 
-   
-      <bean id=“topicListenerB” class=“org.springframework.jms.listener.adapter.MessageListenerAdapter”> 
-          <constructor-arg ref=“topicConsumerB” /> 
-           
-          <property name=“defaultListenerMethod” value=“receive” /> 
-           
-          <property name=“messageConverter” ref=“defaultMessageConverter” /> 
-      </bean> 
-   
-      <bean id=“queueListener” class=“org.springframework.jms.listener.adapter.MessageListenerAdapter”> 
-          <constructor-arg ref=“queueConsumer” /> 
-           
-          <property name=“defaultListenerMethod” value=“receive” /> 
-           
-          <property name=“messageConverter” ref=“defaultMessageConverter” /> 
-      </bean> 
 
-  <bean id=“topicListenerA” class=“org.springframework.jms.listener.adapter.MessageListenerAdapter”>  
-  <constructor-arg ref=“topicConsumerA” />  
-    
-  <property name=“defaultListenerMethod” value=“receive” />  
-    
-  <property name=“messageConverter” ref=“defaultMessageConverter” />  
-  </bean>  
-  <bean id=“topicListenerB” class=“org.springframework.jms.listener.adapter.MessageListenerAdapter”>  
-  <constructor-arg ref=“topicConsumerB” />  
-    
-  <property name=“defaultListenerMethod” value=“receive” />  
-    
-  <property name=“messageConverter” ref=“defaultMessageConverter” />  
-  </bean>  
-  <bean id=“queueListener” class=“org.springframework.jms.listener.adapter.MessageListenerAdapter”>  
-  <constructor-arg ref=“queueConsumer” />  
-    
-  <property name=“defaultListenerMethod” value=“receive” />  
-    
-  <property name=“messageConverter” ref=“defaultMessageConverter” />  
-  </bean>  
 
 8. MessageListenerContainer
 有几个MessageListener既有几个MessageListenerContainer
-  <bean id=“topicListenerContainerA” class=“org.springframework.jms.listener.DefaultMessageListenerContainer”> 
-          <property name=“connectionFactory” ref=“jmsConnectionFactory” /> 
-          <property name=“destination” ref=“TOPIC” /> 
-          <property name=“messageListener” ref=“topicListenerA” /> 
-      </bean> 
-   
-      <bean id=“topicListenerContainerB” class=“org.springframework.jms.listener.DefaultMessageListenerContainer”> 
-          <property name=“connectionFactory” ref=“jmsConnectionFactory” /> 
-          <property name=“destination” ref=“TOPIC” /> 
-          <property name=“messageListener” ref=“topicListenerB” /> 
-      </bean> 
-        
-      <bean id=“queueListenerContainer” class=“org.springframework.jms.listener.DefaultMessageListenerContainer”> 
-          <property name=“connectionFactory” ref=“jmsConnectionFactory” /> 
-          <property name=“destination” ref=“QUEUE” /> 
-          <property name=“messageListener” ref=“queueListener” /> 
-      </bean> 
 
-  <bean id=“topicListenerContainerA” class=“org.springframework.jms.listener.DefaultMessageListenerContainer”>  
-  <property name=“connectionFactory” ref=“jmsConnectionFactory” />  
-  <property name=“destination” ref=“TOPIC” />  
-  <property name=“messageListener” ref=“topicListenerA” />  
-  </bean>  
-  <bean id=“topicListenerContainerB” class=“org.springframework.jms.listener.DefaultMessageListenerContainer”>  
-  <property name=“connectionFactory” ref=“jmsConnectionFactory” />  
-  <property name=“destination” ref=“TOPIC” />  
-  <property name=“messageListener” ref=“topicListenerB” />  
-  </bean>  
-  <bean id=“queueListenerContainer” class=“org.springframework.jms.listener.DefaultMessageListenerContainer”>  
-  <property name=“connectionFactory” ref=“jmsConnectionFactory” />  
-  <property name=“destination” ref=“QUEUE” />  
-  <property name=“messageListener” ref=“queueListener” />  
-  </bean>  
 
  Summary
 写spring配置文件的时候, 要把MessageProducer, MessageConsumer,MessageListener,MessageListenerContainer几个地方弄清楚:
- 可以有一个或者多个消息生产者向同一个destination发送消息.
- queue类型的只能有一个消息消费者.
- topic类型的可以有多个消息消费者.
- 每个消费者对应一个MessageListener和一个MessageListenerContainer.
原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/13697.html