打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
spring boot

前言

前面有一篇博客讲到了spring boot整合jms的使用http://blog.csdn.net/liuchuanhong1/article/details/54603546

但是最近遇到一个需求,需要同时使用jms的队列和topic,于是就有了下面的测试代码:

消费者代码

  1. @Component // 必须加此注解,该类才会被作为Message Driven POJO使用  
  2. public class Consumer {  
  3.     @JmsListener(destination = "mytest.queue")  
  4.     public void receiveQueue(TextMessage text) throws Exception {  
  5.         System.out.println(Thread.currentThread().getName()+":Consumer收到的报文为:"+text.getText());  
  6.     }  
  7.       
  8.     @JmsListener(destination="mytest.topic")  
  9.     public void receiveTopic(TextMessage text) throws JMSException{  
  10.         System.out.println(text.getText());  
  11.     }  
  12. }  
生产者代码

  1. @Service("producer")  
  2. public class Producer {  
  3.     @Autowired  
  4.     private JmsMessagingTemplate jmsTemplate;  
  5.       
  6.     public void sendMessage(Destination destination, final String message){  
  7.         jmsTemplate.convertAndSend(destination, message);  
  8.     }  
  9. }  
测试代码

  1. @RunWith(SpringRunner.class)  
  2. @SpringBootTest  
  3. @EnableAsync //开启对Async的支持,否则异步任务不启作用  
  4. public class SpringbootJmsApplicationTests {  
  5.       
  6.     @Autowired  
  7.     private Producer producer;  
  8.       
  9.     @Test  
  10.     public void contextLoads() throws InterruptedException {  
  11.         while(true){  
  12.             Destination destination = new ActiveMQQueue("mytest.queue");  
  13.             Destination topic = new ActiveMQTopic("mytest.topic");  
  14.               
  15.             for(int i=0; i<100; i++){  
  16.                 producer.sendMessage(destination, "myname is chhliu!!!"+i);  
  17.                 producer.sendMessage(topic, "i'm the king of the world!");  
  18.             }  
  19.         }  
  20.     }  
  21. }  
测试结果如下:

  1. DefaultMessageListenerContainer-6:Consumer收到的报文为:myname is chhliu!!!0  
  2. DefaultMessageListenerContainer-3:Consumer收到的报文为:myname is chhliu!!!1  
  3. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!2  
  4. DefaultMessageListenerContainer-4:Consumer收到的报文为:myname is chhliu!!!3  
  5. DefaultMessageListenerContainer-5:Consumer收到的报文为:myname is chhliu!!!4  
  6. DefaultMessageListenerContainer-2:Consumer收到的报文为:myname is chhliu!!!5  
  7. DefaultMessageListenerContainer-6:Consumer收到的报文为:myname is chhliu!!!6  
  8. DefaultMessageListenerContainer-3:Consumer收到的报文为:myname is chhliu!!!7  
  9. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!8  
  10. DefaultMessageListenerContainer-4:Consumer收到的报文为:myname is chhliu!!!9  
发现一个奇怪的现象,貌似topic没有起效果。于是在配置文件中加了一个配置,配置如下:

  1. spring.jms.pub-sub-domain=true  
然后再跑了一遍上面的测试代码,测试结果如下:

  1. i'm the king of the world!  
  2. i'm the king of the world!  
  3. i'm the king of the world!  
  4. i'm the king of the world!  
  5. i'm the king of the world!  
  6. i'm the king of the world!  
  7. i'm the king of the world!  
  8. i'm the king of the world!  
  9. i'm the king of the world!  
  10. i'm the king of the world!  
  11. i'm the king of the world!  
  12. i'm the king of the world!  
  13. i'm the king of the world!  
  14. i'm the king of the world!  
  15. i'm the king of the world!  
  16. i'm the king of the world!  
  17. i'm the king of the world!  
  18. i'm the king of the world!  
  19. i'm the king of the world!  
这次结果是彻底的反了过来,topic生效了,queue却没起作用了。

to be or not to be that's a question!怎么能让两者同时生效了!至少从前面的两次测试结果可以看出,控制哪个生效,是通过设置pubsubdomain来实现的,于是我们解决方案的出发点也在此。

解决方案如下:

  1. @Configuration  
  2. @EnableJms  
  3. public class JmsConfig {  
  4.     @Bean  
  5.     public JmsListenerContainerFactory<?> topicListenerFactory(ConnectionFactory connectionFactory) {  
  6.         DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();  
  7.         factory.setPubSubDomain(true);  
  8.         factory.setConnectionFactory(connectionFactory);  
  9.         return factory;  
  10.     }  
  11.   
  12.     @Bean  
  13.     public JmsListenerContainerFactory<?> queueListenerFactory(ConnectionFactory connectionFactory) {  
  14.         DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();  
  15.         factory.setPubSubDomain(false);  
  16.         factory.setConnectionFactory(connectionFactory);  
  17.         return factory;  
  18.     }  
  19. }  
上面的代码的作用是创建了两个JmsListenerContainerFactory,分别是topicListenerFactory和queueListenerFactory,其中topicListenerFactory创建的时候,将pubSubDomain设置成了true,表示该Listener负责处理Topic;queueListenerFactory创建的时候,将pubSubDomain设置成了false,也就是说,jms默认就是queue模式,该Listener主要负责处理Queue。

修改消费者代码:

  1. @Component // 必须加此注解,该类才会被作为Message Driven POJO使用  
  2. public class Consumer {  
  3.     @JmsListener(destination = "mytest.queue" ,containerFactory="queueListenerFactory")// 增加对应处理的监听器工程  
  4.     public void receiveQueue(TextMessage text) throws Exception {  
  5.         System.out.println(Thread.currentThread().getName()+":Consumer收到的报文为:"+text.getText());  
  6.     }  
  7.       
  8.     @JmsListener(destination="mytest.topic", containerFactory="topicListenerFactory")// 增加对应处理的监听器工程  
  9.     public void receiveTopic(TextMessage text) throws JMSException{  
  10.         System.out.println(text.getText());  
  11.     }  
  12. }  
再跑一下前面的测试,结果如下:

  1. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!1  
  2. i'm the king of the world!  
  3. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!2  
  4. i'm the king of the world!  
  5. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!3  
  6. i'm the king of the world!  
  7. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!4  
  8. i'm the king of the world!  
  9. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!5  
  10. i'm the king of the world!  
  11. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!6  
  12. i'm the king of the world!  
  13. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!7  
  14. i'm the king of the world!  
  15. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!8  
  16. i'm the king of the world!  
  17. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!9  
  18. i'm the king of the world!  
  19. DefaultMessageListenerContainer-1:Consumer收到的报文为:myname is chhliu!!!10  
  20. i'm the king of the world!  
我们发现,Queue和Topic都生效了。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
跟《泰坦尼克号》学地道表达:我是天下第一!
来~喝下这碗鸡汤,整个世界都是你的!You're the king of the world!
听音悦:Blue 2015回归新单《King of the World》超清MV
搭建logstash+kibana+elasticsearch+redis搭建集中式日志分析平台
China overtakes India as top gold consumer
(Java学习)Hello World
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服