热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

springboot集成ativemq

背景:如果你想在springboot中使用activemq,你可以有两个选择,第一个就是使用内置的activemq,还可以使

背景:

       如果你想在springboot中使用activemq,你可以有两个选择,第一个就是使用内置的activemq,还可以使用外部的activemq,我在这里主要使用了外部的activemq,我是在windows下部署的activemq,不要忘记先启动它。

第一步:添加maven依赖

org.springframework.bootspring-boot-starter-activemq


org.apache.activemqactivemq-pool

第二步:配置applicaiton.properties配置文件

#配置activemq的连接地址
spring.activemq.broker-url=tcp://127.0.0.1:61616
#配置用户名
spring.activemq.user=admin
#配置密码
spring.activemq.password=admin
#true表示使用连接池,false表示不使用连接池;当为false时,每发送一条数据创建一个连接
spring.activemq.pool.enabled=true
#连接池最大连接数
spring.activemq.pool.max-connections=10
#空闲的连接过期时间,默认为30s
spring.activemq.pool.idle-timeout=30000
#强制的连接过期时间,与idleTimeout的区别在于:idleTimeout是在连接空闲一段时间失效,而expiryTimeout不管当前连接的情况,只要达到指定时间就失效。默认为0,never
spring.activemq.pool.expiry-timeout=0

第三步:编写相应代码

       1、我把生产者消费者都集成在了一个项目中,项目结构图如下所示:

       2、定义activemq的主题类型和名称,我们这里定义了主题模式(名称为activemq.topic)和队列模式(名称为activemq.queue)

import javax.jms.Queue;
import javax.jms.Topic;import org.apache.activemq.command.ActiveMQQueue;
import org.apache.activemq.command.ActiveMQTopic;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class ActivemqConfig {// 定义队列模式@Beanpublic Queue queue1() {return new ActiveMQQueue("activemq.queue");}//定义主题模式@Beanpublic Topic topic() {return new ActiveMQTopic("activemq.topic");}}

       3、定义一个消息的提供者MessageProvider,使用一个定时任务来持续的发送数据,这里提供两种消息的发送方式,使用哪一种方式都可以,它们之间的差异性我们后续会分析,方式一(强烈不推荐):

@Configuration
public class MessageProvider1 {@Autowiredprivate JmsMessagingTemplate jmsMessagingTemplate;@Scheduled(fixedRate=5000,initialDelay=3000)public void send() {// 向队列发送消息jmsMessagingTemplate.convertAndSend("activemq.queue", Math.random());// 向主题发送消息jmsMessagingTemplate.convertAndSend("activemq.topic", Math.random());}
}

           下面是方式二,此时可以发现系统并没有指定queue的名称和topic的名称。

@Configuration
public class MessageProvider2 {@Autowiredprivate JmsMessagingTemplate jmsMessagingTemplate;@Autowiredprivate Queue queue;@Autowiredprivate Topic topic;@Scheduled(fixedRate=5000,initialDelay=3000)public void send() {// 向队列发送消息jmsMessagingTemplate.convertAndSend(queue, Math.random()); // 向主题发送消息jmsMessagingTemplate.convertAndSend(topic, Math.random());}
}

       4、定义一个消息的消费者MessageCustomer

@Component
public class MessageCustomer {@JmsListener(destination = "activemq.queue")public void q1(String text) {System.out.println("消费者consumer0消费的消息为:"+text);}@JmsListener(destination = "activemq.queue")public void q2(String text) {System.out.println("消费者consumer1消费的消息为:"+text);}@JmsListener(destination = "activemq.topic")public void t1(String text) {System.out.println("消费者consumer2消费的消息为:"+text);}@JmsListener(destination = "activemq.topic")public void t2(String text) {System.out.println("消费者consumer3消费的消息为:"+text);}
}

       5、定义启动类Application

@SpringBootApplication
@EnableScheduling
// 启动消息队列
@EnableJms
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

第四步:使用MessageProvider2进行测试

       1、我们首先采用MessageProvider2的方式进行测试,启动程序,输出结果如下所示,我们发现输出结果并不是我们想要的那种结果,如果是我们想要的结果输出结果还得打印消费者consumer2消费者consumer3消费的消息。

      2、结果分析:原来springboot默认采用的是p2p模式(队列)进行消息的监听。所以无法监听到topic模式的消息,那么如何对topic模式的消息进行监听呢?只需要在applicaiton.properties里面加上这样一个属性:

spring.jms.pub-sub-domain=true

       3、重启项目,输出结果如下图所示,此时topic模式的消息正常消费,但是队列模式的消息又无法正常消费,原因是springboot默认只支持一种类型消息的消费,那么如何支持两种呢?我们后面会说。

第五步:使用MessageProvider1进行测试

       1、我们首先注释掉刚才加在application.properties里面加的spring.jms.pub-sub-domain=true,启动项目,输出结果如下所示:

       2、我们发现输出结果并不是我们想要的,springboot默认支持队列模式的消息监听,但是当我门发送消息时,只是指定了消息接收方的名字,并没有指定消息接收方的类型,所以springboot默认将这两个消息提供者都看成了队列类型。所以才会出现现在的结果。

       3、在application.properties里面加上spring.jms.pub-sub-domain=true,重启项目,输出结果如下所示:

       4、我们发现只是将队列类型改成了主题类型,从根本上还是没有解决我们的问题,我们想让springboot既支持队列模式又支持主题模式。 

第六步:springboot同时支持topic和queue

       1、注释掉在application.properties里面加的spring.jms.pub-sub-domain=true

       2、在ActivemqConfig这个类里面重新定义两个bean

@Configuration
public class ActivemqConfig {// 定义队列模式@Beanpublic Queue queue() {return new ActiveMQQueue("activemq.queue");}//定义主题模式@Beanpublic Topic topic() {return new ActiveMQTopic("activemq.topic");}@Beanpublic JmsListenerContainerFactory topicListenerContainerFactory(ConnectionFactory connectionFactory){DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();factory.setPubSubDomain(true);factory.setConnectionFactory(connectionFactory);return factory;}@Beanpublic JmsListenerContainerFactory queueListenerContainerFactory(ConnectionFactory connectionFactory){DefaultJmsListenerContainerFactory factory = new DefaultJmsListenerContainerFactory();factory.setPubSubDomain(false);factory.setConnectionFactory(connectionFactory);return factory;}
}

       3、在MessageCustomer的方法注解JmsListener上添加属性containerFactory属性

@Component
public class MessageCustomer {@JmsListener(destination = "activemq.queue",containerFactory = "queueListenerContainerFactory")public void q1(String text) {System.out.println("消费者consumer0消费的消息为:"+text); }@JmsListener(destination = "activemq.queue",containerFactory = "queueListenerContainerFactory") public void q2(String text) {System.out.println("消费者consumer1消费的消息为:"+text); }@JmsListener(destination = "activemq.topic",containerFactory = "topicListenerContainerFactory")public void t1(String text) {System.out.println("消费者consumer2消费的消息为:"+text);}@JmsListener(destination = "activemq.topic",containerFactory = "topicListenerContainerFactory")public void t2(String text) {System.out.println("消费者consumer3消费的消息为:"+text);}
}

       4、重启项目,输出结果如下,我们发现现在的结果就是同时支持了queue模式和topic模式。

 

第七步:遇坑分析

        1、一直以为在activemq的管理界面中点击Queues里面显示的创建了多少个queue(队列)模式的主题,这个理解是错误的。其实这里面显示的信息是“MessageCustomer里面监听(destination)的(所有监听的主题和类型都会出现在这里,不论它是队列模式还是主题模式)+你自己创建的队列类型的主题”

       我们在destination中监听了activemq.queueactivemq.topic这两个,但我们创建了activemq.queue2队列activemq.topic2主题,并向它们分别发送了消息,注意:如果不向activemq.queue2activemq.topic2发送消息,仅仅是定义了一个bean,那么activemq就发现不了它们两个。此时的Queues的组成就是监听的activemq.queueactivemq.topic+创建的activemq.queue2。

       2、如果我们想看我们定义的topic,进入到Topics下查看即可。

 


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 标题: ... [详细]
  • Android工程师面试准备及设计模式使用场景
    本文介绍了Android工程师面试准备的经验,包括面试流程和重点准备内容。同时,还介绍了建造者模式的使用场景,以及在Android开发中的具体应用。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文介绍了在Win10上安装WinPythonHadoop的详细步骤,包括安装Python环境、安装JDK8、安装pyspark、安装Hadoop和Spark、设置环境变量、下载winutils.exe等。同时提醒注意Hadoop版本与pyspark版本的一致性,并建议重启电脑以确保安装成功。 ... [详细]
  • Activiti7流程定义开发笔记
    本文介绍了Activiti7流程定义的开发笔记,包括流程定义的概念、使用activiti-explorer和activiti-eclipse-designer进行建模的方式,以及生成流程图的方法。还介绍了流程定义部署的概念和步骤,包括将bpmn和png文件添加部署到activiti数据库中的方法,以及使用ZIP包进行部署的方式。同时还提到了activiti.cfg.xml文件的作用。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • 本文介绍了在Mac上搭建php环境后无法使用localhost连接mysql的问题,并通过将localhost替换为127.0.0.1或本机IP解决了该问题。文章解释了localhost和127.0.0.1的区别,指出了使用socket方式连接导致连接失败的原因。此外,还提供了相关链接供读者深入了解。 ... [详细]
author-avatar
手机用户2502939965
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有