rabbitmq整合spring

来源:互联网 发布:网络上黄泉 漫画 编辑:程序博客网 时间:2024/05/21 08:52

这两天闲着没事玩了下RabbitMQ.

MQ全称为Message Queue, (MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求..

RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统。他遵循Mozilla Public License开源协议

关于基本的介绍网上太多了..我这里就不赘述了.exchange, queue, channel这些基本概念也就说了.

只介绍一点, exchange一般用的有三种, 有兴趣童鞋可以参考此博客-----> 点这里.


开始正题!

在开发之前需要下载rabbitmq, 而在rabbitmq安装之前,童鞋们需要安装erlang, 因为rabbitmq是用erlang写的.

安装完毕之后,我们建立一个maven项目.然后我们开始配置项目.

由于是spring整合,我们需要加入spring的依赖.

弄个可以跑的spring项目

 

[java] view plain copy
  1. <!-- spring版本号 -->  
  2. <spring.version>3.2.8.RELEASE</spring.version>  
  3. <!-- 添加Spring依赖 -->  
  4. <dependency>  
  5.     <groupId>org.springframework</groupId>  
  6.     <artifactId>spring-core</artifactId>  
  7.     <version>${spring.version}</version>  
  8. </dependency>  
  9. <dependency>  
  10.     <groupId>org.springframework</groupId>  
  11.     <artifactId>spring-webmvc</artifactId>  
  12.     <version>${spring.version}</version>  
  13. </dependency>  
  14. <dependency>  
  15.     <groupId>org.springframework</groupId>  
  16.     <artifactId>spring-context</artifactId>  
  17.     <version>${spring.version}</version>  
  18. </dependency>  
  19. <dependency>  
  20.     <groupId>org.springframework</groupId>  
  21.     <artifactId>spring-context-support</artifactId>  
  22.     <version>${spring.version}</version>  
  23. </dependency>  
  24. <dependency>  
  25.     <groupId>org.springframework</groupId>  
  26.     <artifactId>spring-aop</artifactId>  
  27.     <version>${spring.version}</version>  
  28. </dependency>  
  29. <dependency>  
  30.     <groupId>org.springframework</groupId>  
  31.     <artifactId>spring-aspects</artifactId>  
  32.     <version>${spring.version}</version>  
  33. </dependency>  
  34. <dependency>  
  35.     <groupId>org.springframework</groupId>  
  36.     <artifactId>spring-tx</artifactId>  
  37.     <version>${spring.version}</version>  
  38. </dependency>  
  39. <dependency>  
  40.     <groupId>org.springframework</groupId>  
  41.     <artifactId>spring-jdbc</artifactId>  
  42.     <version>${spring.version}</version>  
  43. </dependency>  
  44. <dependency>  
  45.     <groupId>org.springframework</groupId>  
  46.     <artifactId>spring-web</artifactId>  
  47.     <version>${spring.version}</version>  
  48. </dependency>  

 

然后加入rabbitmq和spring的整合依赖

[java] view plain copy
  1. <!--rabbitmq依赖 -->  
  2. <dependency>  
  3.     <groupId>org.springframework.amqp</groupId>  
  4.     <artifactId>spring-rabbit</artifactId>  
  5.     <version>1.3.5.RELEASE</version>  
  6. </dependency>  

 

依赖加好了之后, 我们需要定义消息生产者和消息发送者.

由于exchange有几种,这里我只测试了两种, 通过分别定义两个exchange去绑定direct和topic..

首先, 定义消息生产者, 通过配置将template链接connect-factory并注入到代码中使用.

[java] view plain copy
  1. package com.chris.producer;  
  2.   
  3. import org.slf4j.Logger;  
  4. import org.slf4j.LoggerFactory;  
  5. import org.springframework.amqp.core.AmqpTemplate;  
  6. import org.springframework.stereotype.Service;  
  7.   
  8. import javax.annotation.Resource;  
  9. import java.io.IOException;  
  10.   
  11. /** 
  12.  * Created by wuxing on 2016/9/21. 
  13.  */  
  14. @Service  
  15. public class MessageProducer {  
  16.   
  17.     private Logger logger = LoggerFactory.getLogger(MessageProducer.class);  
  18.   
  19.     @Resource(name="amqpTemplate")  
  20.     private AmqpTemplate amqpTemplate;  
  21.   
  22.     @Resource(name="amqpTemplate2")  
  23.     private AmqpTemplate amqpTemplate2;  
  24.   
  25.     public void sendMessage(Object message) throws IOException {  
  26.         logger.info("to send message:{}", message);  
  27.         amqpTemplate.convertAndSend("queueTestKey", message);  
  28.         amqpTemplate.convertAndSend("queueTestChris", message);  
  29.   
  30.         amqpTemplate2.convertAndSend("wuxing.xxxx.wsdwd", message);  
  31.     }  
  32. }  


然后我们定义消息消费者, 这里,我定义了三个消费者, 通过监听消息队列, 分别接受各自所匹配的消息.

第一个消费者, 接受direct的消息, 他的exchange为exchangeTest,  rout-key为queueTestKey

[java] view plain copy
  1. package com.chris.consumer;  
  2.   
  3. import org.slf4j.Logger;  
  4. import org.slf4j.LoggerFactory;  
  5. import org.springframework.amqp.core.Message;  
  6. import org.springframework.amqp.core.MessageListener;  
  7.   
  8. /** 
  9.  * Created by wuxing on 2016/9/21. 
  10.  */  
  11. public class MessageConsumer implements MessageListener {  
  12.   
  13.     private Logger logger = LoggerFactory.getLogger(MessageConsumer.class);  
  14.   
  15.     @Override  
  16.     public void onMessage(Message message) {  
  17.         logger.info("consumer receive message------->:{}", message);  
  18.     }  
  19.   
  20. }  


第二个消费者, 接受direct的消息(为了测试一个exchange可以发送多个消息), 他的exchange为exchangeTest,  rout-key为queueTestChris.

[java] view plain copy
  1. package com.chris.consumer;  
  2.   
  3. import org.slf4j.Logger;  
  4. import org.slf4j.LoggerFactory;  
  5. import org.springframework.amqp.core.Message;  
  6. import org.springframework.amqp.core.MessageListener;  
  7.   
  8. /** 
  9.  * Created by wuxing on 2016/9/21. 
  10.  */  
  11. public class ChrisConsumer implements MessageListener {  
  12.     private Logger logger = LoggerFactory.getLogger(ChrisConsumer.class);  
  13.   
  14.     @Override  
  15.     public void onMessage(Message message) {  
  16.         logger.info("chris receive message------->:{}", message);  
  17.     }  
  18. }  


第三个消费者, 接受topic的消息他的exchange为exchangeTest2,  pattern为wuxing.*.. 网上说.*可以匹配一个, .#可以匹配一个或多个..

但是笔者好像两个都试了..都可以匹配一个或多个..不知道什么鬼...

[java] view plain copy
  1. package com.chris.consumer;  
  2.   
  3. import org.slf4j.Logger;  
  4. import org.slf4j.LoggerFactory;  
  5. import org.springframework.amqp.core.Message;  
  6. import org.springframework.amqp.core.MessageListener;  
  7.   
  8. /** 
  9.  * Created by wuxing on 2016/9/21. 
  10.  */  
  11. public class WuxingConsumer implements MessageListener {  
  12.     private Logger logger = LoggerFactory.getLogger(WuxingConsumer.class);  
  13.   
  14.     @Override  
  15.     public void onMessage(Message message) {  
  16.         logger.info("wuxing receive message------->:{}", message);  
  17.     }  
  18. }  


然后就是关键的地方了..rabbit整合spring的配置文件.

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:rabbit="http://www.springframework.org/schema/rabbit"  
  4.        xsi:schemaLocation="http://www.springframework.org/schema/beans  
  5.      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
  6.      http://www.springframework.org/schema/rabbit  
  7.      http://www.springframework.org/schema/rabbit/spring-rabbit-1.2.xsd">  
  8.     <!--配置connection-factory,指定连接rabbit server参数 -->  
  9.     <rabbit:connection-factory id="connectionFactory"  
  10.                                username="guest" password="guest" host="localhost" port="5672" />  
  11.   
  12.     <!--定义rabbit template用于数据的接收和发送 -->  
  13.     <rabbit:template id="amqpTemplate" connection-factory="connectionFactory"  
  14.                      exchange="exchangeTest"/>  
  15.   
  16.     <!--通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成 -->  
  17.     <rabbit:admin id="connectAdmin" connection-factory="connectionFactory"/>  
  18.   
  19.     <!--定义queue -->  
  20.     <rabbit:queue name="queueTest" durable="true" auto-delete="false" exclusive="false" declared-by="connectAdmin"/>  
  21.   
  22.     <!-- 定义direct exchange,绑定queueTest -->  
  23.     <rabbit:direct-exchange name="exchangeTest" durable="true" auto-delete="false" declared-by="connectAdmin">  
  24.         <rabbit:bindings>  
  25.             <rabbit:binding queue="queueTest" key="queueTestKey"></rabbit:binding>  
  26.         </rabbit:bindings>  
  27.     </rabbit:direct-exchange>  
  28.   
  29.     <!-- 消息接收者 -->  
  30.     <bean id="messageReceiver" class="com.chris.consumer.MessageConsumer"></bean>  
  31.   
  32.     <!-- queue litener  观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象-->  
  33.     <rabbit:listener-container connection-factory="connectionFactory">  
  34.         <rabbit:listener queues="queueTest" ref="messageReceiver"/>  
  35.     </rabbit:listener-container>  
  36.   
  37.     <!--定义queue -->  
  38.     <rabbit:queue name="queueChris" durable="true" auto-delete="false" exclusive="false" declared-by="connectAdmin"/>  
  39.   
  40.     <!-- 定义direct exchange,绑定queueTest -->  
  41.     <rabbit:direct-exchange name="exchangeTest" durable="true" auto-delete="false" declared-by="connectAdmin">  
  42.         <rabbit:bindings>  
  43.             <rabbit:binding queue="queueChris" key="queueTestChris"></rabbit:binding>  
  44.         </rabbit:bindings>  
  45.     </rabbit:direct-exchange>  
  46.   
  47.     <!-- 消息接收者 -->  
  48.     <bean id="receiverChris" class="com.chris.consumer.ChrisConsumer"></bean>  
  49.   
  50.     <!-- queue litener  观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象-->  
  51.     <rabbit:listener-container connection-factory="connectionFactory">  
  52.         <rabbit:listener queues="queueChris" ref="receiverChris"/>  
  53.     </rabbit:listener-container>  
  54.   
  55.     <!--              分隔线                -->  
  56.     <!--配置connection-factory,指定连接rabbit server参数 -->  
  57.     <rabbit:connection-factory id="connectionFactory2"  
  58.                                username="guest" password="guest" host="localhost" port="5672"/>  
  59.   
  60.     <!--定义rabbit template用于数据的接收和发送 -->  
  61.     <rabbit:template id="amqpTemplate2" connection-factory="connectionFactory2"  
  62.                      exchange="exchangeTest2"/>  
  63.   
  64.     <!--通过指定下面的admin信息,当前producer中的exchange和queue会在rabbitmq服务器上自动生成 -->  
  65.     <rabbit:admin id="connectAdmin2" connection-factory="connectionFactory2"/>  
  66.   
  67.     <!--定义queue -->  
  68.     <rabbit:queue name="queueWuxing" durable="true" auto-delete="false" exclusive="false" declared-by="connectAdmin2"/>  
  69.   
  70.     <!-- 定义direct exchange,绑定queueTest -->  
  71.     <rabbit:topic-exchange name="exchangeTest2" durable="true" auto-delete="false" declared-by="connectAdmin2">  
  72.         <rabbit:bindings>  
  73.             <rabbit:binding queue="queueWuxing" pattern="wuxing.*"></rabbit:binding>  
  74.         </rabbit:bindings>  
  75.     </rabbit:topic-exchange>  
  76.   
  77.     <!-- 消息接收者 -->  
  78.     <bean id="recieverWuxing" class="com.chris.consumer.WuxingConsumer"></bean>  
  79.   
  80.     <!-- queue litener  观察 监听模式 当有消息到达时会通知监听在对应的队列上的监听对象-->  
  81.     <rabbit:listener-container connection-factory="connectionFactory2" >  
  82.         <rabbit:listener queues="queueWuxing" ref="recieverWuxing"/>  
  83.     </rabbit:listener-container>  
  84. </beans>  

 

这里,有个问题笔者研究了好久...就是如何定义两个exchange, 一开始一直不成功..直到找到了一篇国外的文章才解决...

定义两个exchange的时候, 需要用到declared-by..

而这个必须要引入下面的这个申明, 才有..

[html] view plain copy
  1. http://www.springframework.org/schema/rabbit  
  2.      http://www.springframework.org/schema/rabbit/spring-rabbit-1.2.xsd">  

 

文件中大概的配置解释一下.

connect-factory进行连接rabbitmq服务.

template用于连接factory并指定exchange, 这上面还能直接指定rout-key.

admin相当于一个管理员的角色..可以将exchange和queue进行管理, 

queue和topic-exchange分别定义队列和路由器, 这里需要用declared-by指定管理员,从而连接到相应的factory.

listener-container用于消费者的监听(其实,rabbit配置中是可以指定某个类的某个方法的, 但是笔者失败了, 还在试验中...)


这里还有一个问题...需要大家注意..

当一个exchange绑定了一种类型之后, 这个exchange在配置就不能再换成另一种了.会一直报错, received 'direct' but current is 'topic'  类似这种..

笔者这个也是被坑了若干时间去找问题...


然后贴下spring的基本配置

[html] view plain copy
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans xmlns="http://www.springframework.org/schema/beans"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
  5.     http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">  
  6.   
  7.     <import resource="classpath*:rabbitmq.xml" />  
  8.       
  9.     <!-- 扫描指定package下所有带有如@controller,@services,@resource,@ods并把所注释的注册为Spring Beans -->  
  10.     <context:component-scan base-package="com.chris.consumer, com.chris.producer" />  
  11.       
  12.     <!-- 激活annotation功能 -->  
  13.     <context:annotation-config />  
  14.     <!-- 激活annotation功能  会报错,没啥用 -->  
  15.     <!-- <context:spring-configured />  -->
  16.   
  17. </beans>  


然后是单元测试类, 这里通过输出100-1慢慢递减,去观察控制台消费者接收消息的情况.

[java] view plain copy
  1. package com.chris;  
  2.   
  3. import com.chris.producer.MessageProducer;  
  4. import org.junit.Before;  
  5. import org.junit.Test;  
  6. import org.slf4j.Logger;  
  7. import org.slf4j.LoggerFactory;  
  8. import org.springframework.context.ApplicationContext;  
  9. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  10.   
  11. /** 
  12.  * Created by wuxing on 2016/9/21. 
  13.  */  
  14. public class MessageTest {  
  15.   
  16.     private Logger logger = LoggerFactory.getLogger(MessageTest.class);  
  17.   
  18.     private ApplicationContext context = null;  
  19.   
  20.     @Before  
  21.     public void setUp() throws Exception {  
  22.         context = new ClassPathXmlApplicationContext("application.xml");  
  23.     }  
  24.   
  25.     @Test  
  26.     public void should_send_a_amq_message() throws Exception {  
  27.         MessageProducer messageProducer = (MessageProducer) context.getBean("messageProducer");  
  28.         int a = 100;  
  29.         while (a > 0) {  
  30.             messageProducer.sendMessage("Hello, I am amq sender num :" + a--);  
  31.             try {  
  32.                 //暂停一下,好让消息消费者去取消息打印出来  
  33.                 Thread.sleep(1000);  
  34.             } catch (InterruptedException e) {  
  35.                 e.printStackTrace();  
  36.             }  
  37.   
  38.         }  
  39.     }  
  40. }  



然后控制台的结果如下(这里只贴出关键信息, 其他配置的log的省略了)

[java] view plain copy
  1. 2016-09-22 16:15:00,330 [main] INFO  [com.chris.producer.MessageProducer] - to send message:Hello, I am amq sender num :100  
  2. 2016-09-22 16:15:00,348 [main] DEBUG [org.springframework.amqp.rabbit.connection.CachingConnectionFactory] - Creating cached Rabbit Channel from AMQChannel(amqp://guest@127.0.0.1:5672/,3)  
  3. 2016-09-22 16:15:00,348 [main] DEBUG [org.springframework.amqp.rabbit.core.RabbitTemplate] - Executing callback on RabbitMQ Channel: Cached Rabbit Channel: AMQChannel(amqp://guest@127.0.0.1:5672/,3)  
  4. 2016-09-22 16:15:00,349 [main] DEBUG [org.springframework.amqp.rabbit.core.RabbitTemplate] - Publishing message on exchange [exchangeTest], routingKey = [queueTestKey]  
  5. 2016-09-22 16:15:00,357 [main] DEBUG [org.springframework.amqp.rabbit.core.RabbitTemplate] - Executing callback on RabbitMQ Channel: Cached Rabbit Channel: AMQChannel(amqp://guest@127.0.0.1:5672/,3)  
  6. 2016-09-22 16:15:00,358 [main] DEBUG [org.springframework.amqp.rabbit.core.RabbitTemplate] - Publishing message on exchange [exchangeTest], routingKey = [queueTestChris]  
  7. 2016-09-22 16:15:00,368 [main] DEBUG [org.springframework.amqp.rabbit.connection.CachingConnectionFactory] - Creating cached Rabbit Channel from AMQChannel(amqp://guest@127.0.0.1:5672/,2)  
  8. 2016-09-22 16:15:00,369 [main] DEBUG [org.springframework.amqp.rabbit.core.RabbitTemplate] - Executing callback on RabbitMQ Channel: Cached Rabbit Channel: AMQChannel(amqp://guest@127.0.0.1:5672/,2)  
  9. 2016-09-22 16:15:00,369 [main] DEBUG [org.springframework.amqp.rabbit.core.RabbitTemplate] - Publishing message on exchange [exchangeTest2], routingKey = [wuxing.xxxx.wsdwd]  
  10. 2016-09-22 16:15:00,370 [pool-1-thread-6] DEBUG [org.springframework.amqp.rabbit.listener.BlockingQueueConsumer] - Storing delivery for Consumer: tags=[[amq.ctag-hyW85GZHk-AHLLFJUmNLDQ]], channel=Cached Rabbit Channel: AMQChannel(amqp://guest@127.0.0.1:5672/,1), acknowledgeMode=AUTO local queue size=0  
  11. 2016-09-22 16:15:00,372 [SimpleAsyncTaskExecutor-1] DEBUG [org.springframework.amqp.rabbit.listener.BlockingQueueConsumer] - Received message: (Body:'Hello, I am amq sender num :100'MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, appId=null, clusterId=null, type=null, correlationId=null, replyTo=null, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, deliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=exchangeTest, receivedRoutingKey=queueTestKey, deliveryTag=1, messageCount=0])  
  12. 2016-09-22 16:15:00,373 [SimpleAsyncTaskExecutor-1] INFO  [com.chris.consumer.MessageConsumer] - consumer receive message------->:(Body:'Hello, I am amq sender num :100'MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, appId=null, clusterId=null, type=null, correlationId=null, replyTo=null, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, deliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=exchangeTest, receivedRoutingKey=queueTestKey, deliveryTag=1, messageCount=0])  
  13. 2016-09-22 16:15:00,374 [SimpleAsyncTaskExecutor-1] DEBUG [org.springframework.amqp.rabbit.listener.BlockingQueueConsumer] - Retrieving delivery for Consumer: tags=[[amq.ctag-hyW85GZHk-AHLLFJUmNLDQ]], channel=Cached Rabbit Channel: AMQChannel(amqp://guest@127.0.0.1:5672/,1), acknowledgeMode=AUTO local queue size=0  
  14. 2016-09-22 16:15:00,379 [pool-2-thread-4] DEBUG [org.springframework.amqp.rabbit.listener.BlockingQueueConsumer] - Storing delivery for Consumer: tags=[[amq.ctag-T-c1red0T_HHyCFfpXLYIQ]], channel=Cached Rabbit Channel: AMQChannel(amqp://guest@127.0.0.1:5672/,1), acknowledgeMode=AUTO local queue size=0  
  15. 2016-09-22 16:15:00,381 [SimpleAsyncTaskExecutor-1] DEBUG [org.springframework.amqp.rabbit.listener.BlockingQueueConsumer] - Received message: (Body:'Hello, I am amq sender num :100'MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, appId=null, clusterId=null, type=null, correlationId=null, replyTo=null, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, deliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=exchangeTest2, receivedRoutingKey=wuxing.xxxx.wsdwd, deliveryTag=1, messageCount=0])  
  16. 2016-09-22 16:15:00,382 [SimpleAsyncTaskExecutor-1] INFO  [com.chris.consumer.WuxingConsumer] - wuxing receive message------->:(Body:'Hello, I am amq sender num :100'MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, appId=null, clusterId=null, type=null, correlationId=null, replyTo=null, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, deliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=exchangeTest2, receivedRoutingKey=wuxing.xxxx.wsdwd, deliveryTag=1, messageCount=0])  
  17. 2016-09-22 16:15:00,383 [SimpleAsyncTaskExecutor-1] DEBUG [org.springframework.amqp.rabbit.listener.BlockingQueueConsumer] - Retrieving delivery for Consumer: tags=[[amq.ctag-T-c1red0T_HHyCFfpXLYIQ]], channel=Cached Rabbit Channel: AMQChannel(amqp://guest@127.0.0.1:5672/,1), acknowledgeMode=AUTO local queue size=0  
  18. 2016-09-22 16:15:00,396 [pool-1-thread-5] DEBUG [org.springframework.amqp.rabbit.listener.BlockingQueueConsumer] - Storing delivery for Consumer: tags=[[amq.ctag-h5ERpaWrnqmkNhbfM7S8Ww]], channel=Cached Rabbit Channel: AMQChannel(amqp://guest@127.0.0.1:5672/,2), acknowledgeMode=AUTO local queue size=0  
  19. 2016-09-22 16:15:00,397 [SimpleAsyncTaskExecutor-1] DEBUG [org.springframework.amqp.rabbit.listener.BlockingQueueConsumer] - Received message: (Body:'Hello, I am amq sender num :100'MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, appId=null, clusterId=null, type=null, correlationId=null, replyTo=null, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, deliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=exchangeTest, receivedRoutingKey=queueTestChris, deliveryTag=1, messageCount=0])  
  20. 2016-09-22 16:15:00,398 [SimpleAsyncTaskExecutor-1] INFO  [com.chris.consumer.ChrisConsumer] - chris receive message------->:(Body:'Hello, I am amq sender num :100'MessageProperties [headers={}, timestamp=null, messageId=null, userId=null, appId=null, clusterId=null, type=null, correlationId=null, replyTo=null, contentType=text/plain, contentEncoding=UTF-8, contentLength=0, deliveryMode=PERSISTENT, expiration=null, priority=0, redelivered=false, receivedExchange=exchangeTest, receivedRoutingKey=queueTestChris, deliveryTag=1, messageCount=0])  
  21. 2016-09-22 16:15:00,400 [SimpleAsyncTaskExecutor-1] DEBUG [org.springframework.amqp.rabbit.listener.BlockingQueueConsumer] - Retrieving delivery for Consumer: tags=[[amq.ctag-h5ERpaWrnqmkNhbfM7S8Ww]], channel=Cached Rabbit Channel: AMQChannel(amqp://guest@127.0.0.1:5672/,2), acknowledgeMode=AUTO local queue size=0  


我们可以看到生产者有发出一个信息, 然后发布在了三个通道上.

1. on exchange [exchangeTest] , routingKey = [queueTestKey]

2. on exchange [exchangeTest] , routingKey = [queueTestChris]

3. on exchange [exchangeTest2] , routingKey = [wuxing.xxxx.wsdwd]


然后三个消费者分别收到了他们的消息..至此, 整个test就结束了.

对项目有兴趣的童鞋可以拿项目的源码玩一玩  源码在这里


文章中有什么错误或者不妥的地方, 还望大家指正, 和大家共勉!!!

http://blog.csdn.net/wuxingchris/article/details/52623367