SpringBoot activemq收发消息、配置及原理
SpringBoot集成消息处理框架
Spring framework提供了对JMS和AMQP消息框架的无缝集成,为Spring项目使用消息处理框架提供了极大的便利。
与Spring framework相比,Spring Boot更近了一步,通过auto-configuration机制实现了对jms及amqp主流框架如ActiveMQ、RabbitMQ以及Kafka的自动配置,应用层开发过程中无需自己配置,只要classpath下加入了相应的消息处理框架包,Spring Boot会自动完成加载,程序员直接就可以使用,简直不能再方便了。
JMS
The Java Message Service (JMS) API is a messaging standard that allows application components based on the Java Platform Enterprise Edition (Java EE) to create, send, receive, and read messages. It enables distributed communication that is loosely coupled, reliable, and asynchronous.
JMS是java message service的简称,是一个基于java的消息处理规范,允许基于JAVA EE平台的应用组件创建、发送、接收、读取消息。使得分布式通讯耦合度更低、更加可靠、异步处理。
JMS提供两种编程模式:
Point-to-Point—Messages are sent to a single consumer using a JMS queue.
Publish and Subscribe—Messages are broadcast to all registered listeners through JMS topics.
点对点通讯:消息通过队列发送给单一的消费者。
发布订阅模式:消息通过主题以广播的形式发送给所有的订阅者。
JMS规范规定了5种不同类型的消息体:

- StreamMessage:流式消息,顺序读取。
- MapMessage:键值对消息,可顺序读取,也可以通过键随机读取。
- TextMessage:文本消息,当初制定规范时候认为xml会成为最主流的消息载体,通过TextMessage可以发送xml格式的文本数据。
- ObjectMessage:对象消息,java对象序列化后发送。
- BytesMessage:字节消息。
JMS API对消息的发送、接收、存储等操作做了约定,每一个JMS消息框架的提供者(实现者)都必须遵守这些约定。
ActiveMQ
ActiveMQ是Apache旗下的、基于JMS的一款开源消息处理中间件,官网介绍:
Apache ActiveMQ® is the most popular open source, multi-protocol, Java-based message broker. It supports industry standard protocols so users get the benefits of client choices across a broad range of languages and platforms. Connect from clients written in JavaScript, C, C++, Python, .Net, and more. Integrate your multi-platform applications using the ubiquitous AMQP protocol. Exchange messages between your web applications using STOMP over websockets. Manage your IoT devices using MQTT. Support your existing JMS infrastructure and beyond. ActiveMQ offers the power and flexibility to support any messaging use-case.
最流行的开源、多协议、基于JAVA的消息处理中间件。支持工业级协议所以用户可以从多语言、跨平台的客户端选择中受益。等等…
目前ActiveMQ有两个主流版本:

There are currently two “flavors” of ActiveMQ available - the well-known “classic” broker and the “next generation” broker code-named Artemis. Once Artemis reaches a sufficient level of feature parity with the “Classic” code-base it will become the next major version of ActiveMQ. Initial migration documentation is available as well as a development roadmap for Artemis.
等到代表“下一代”的Artemis成熟之后,就会替代“classic”成为ActiveMQ的主版本。
ActiveMQ的下载安装
官网找一个合适的版本下载安装即可,非常简单。
安装后提供了一个管理端口:

可以通过管理端口做测试,管理端口是8161,而默认的MQ服务端口是61616。
SpringBoot项目自动配置ActiveMQ
首先初步了解一下SpringBoot对ActiveMQ的集成情况,轻车熟路的,检查一下auto-configuration:

找到这个JmsAutoConfiguration类:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ Message.class, JmsTemplate.class })
@ConditionalOnBean(ConnectionFactory.class)
@EnableConfigurationProperties(JmsProperties.class)
@Import(JmsAnnotationDrivenConfiguration.class)
public class JmsAutoConfiguration {
很明显,他就是SpringBoot的自动配置类,如果classpath下存在Message.class, JmsTemplate.class 类、以及Spring容器中存在ConnectionFactory Bean的话就会被启用。检查一下代码发现他会自动装配JmsTemplate、JmsMessagingTemplate等对象到Spring IoC容器中。
SpringBoot项目引入ActiveMQ
POM文件引入:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-activemq</artifactId></dependency>
以上starter包含了spring-jms以及activemq的相关配置,所以通过以上对auto-configuration的分析,JmsTemplate以及JmsMessagingTemplate等相关组件会被SpringBoot自动配置好,后面我们就可以直接拿来使用了。
ps:JmsTemplate组件的自动配置过程源码也比较复杂,今天暂时不涉及。
到此,其实我们并没做什么具体的工作,但是ActiveMQ已经准备好了,我们项目中就可以直接使用JmsTemplate收发消息了。
消息发送
在application.yml文件中加入activeMQ的配置:
spring:activemq:broker-url: tcp://localhost:61616user: adminpassword: admin
消息发送类中通过自动装配引入JmsTemplate:
@Autowiredprivate JmsTemplate jmsTemplate;
消息发送方法:
public void sendMessage(String message){jmsTemplate.send("active.myqueue", new MessageCreator() {@Overridepublic Message createMessage(Session session) throws JMSException {// 也可以创建对象 session.createObjectMessage()TextMessage textMessage = session.createTextMessage();textMessage.setText(message);return textMessage;}});}
Controller中加入对sendMessage方法的调用,以便测试:
@GetMapping ("/sendmessage/{msg}")public String sendMessage(@PathVariable String msg){userService.sendMessage(msg);return "hello";}
消息接收
同样,消息接收方法中通过自动装配引入JmsTemplate。
消息接收方法:
public String revieveMessage(){String message = (String)jmsTemplate.receiveAndConvert("active.myqueue");log.info("revieved message:"+message);return message;}
Controller方法中加入接收方法以便测试:
@GetMapping ("/recievemsg")public String recieveMessage(){return userService.revieveMessage();}
这样,activeMQ的“点对点模式”收发消息的代码准备完毕,非常简单。
验证
首先启动activeMQ,启动之后在ActiveMQ的管理端监控队列(截图之前我已经测试过一次消息收发了,如果没测试过的话,队列是空的,不会存在active.myqueue这个队列):

启动我们刚才创建的测试应用,测试发送消息:

发送消息 1230230,收到反馈“hello”,说明消息发送成功。
我们从ActiveMQ管理端查看队列:

Number of pending Message 队列中尚未消费的消息数量为1,说明我们刚才的消息已经成功发送到队列中了。
消息接收测试:

成功接收到消息1230230。
再次从ActiveMQ管理端验证:

队列中的pending message数量变为0,入队数量和出队数量都为1,说明刚才的消息已经被成功消费。
此时,队列中尚未消费的数量为0的情况下,如果再次执行消息消费方法(recievemsg方法),消费方法会阻塞等待,直到再次调用消息发送方法发送一条新消息到队列、消费方法获取到新消息后结束阻塞等待。
监听器方式接收消息
发布订阅模式与点对点模式的区别主要是在消息接收端,Spring提供了接收消息的注解@JmsListener。
@JmsListener需要与@Component家族的注解结合使用,UserService中编写两个listener监听active.listenqueue::
@Service
@Slf4j
public class UserService {@Autowiredprivate JmsTemplate jmsTemplate;@JmsListener(destination = "active.listenqueue")public void revieveMsgListener(String content){log.info("revieveMsgListener:"+ content);}@JmsListener(destination = "active.listenqueue")public void revieveMsgListenerA(String content){log.info("revieveMsgListenerA"+content);}
UserService编写一个向该ActiveMQ发送消息的方法:
public void sendMessage(String message){jmsTemplate.send("active.listenqueue", new MessageCreator() {@Overridepublic Message createMessage(Session session) throws JMSException {// 也可以创建对象 session.createObjectMessage()TextMessage textMessage = session.createTextMessage();textMessage.setText(message);return textMessage;}});}
Controller中调用发送方法:
@GetMapping ("/sendmessage/{msg}")public String sendMessage(@PathVariable String msg){userService.sendMessage(msg);return "hello";}
}
启动activeMQ,启动项目之后,查看activemq的admin端:

active.listenqueue以及2个监听器已经注册到ActiveMQ中,发送消息:

检查应用已经接收到了消息:

但是只有一个监听器接收到了消息,反复发送消息,后台log发现两个监听器轮番收到消息、但是一条消息不能被两个监听器同时接收到:

发布订阅模式
发布订阅模式下,消息发送给topic,订阅者仅订阅感兴趣的topic内的消息,消息消费完成后并不会从topic中消失,多个消费者可以从同一个topic内消费消息,所以,一条消息允许被多次消费。
默认情况下,SpringBoot集成ActiveMQ采用的是点对点队列模式,application.yml文件配置 spring:jms:pub-sub-domain参数为true开启topic模式:
spring:activemq:broker-url: tcp://localhost:61616user: adminpassword: adminjms:pub-sub-domain: true
启动activeMQ,启动项目,topic下看到项目中启动的两个topic:

调用sendmessage方法发送消息:

检查ActiveMQ状态,可以发现1条消息成功发送到队列中,被2个消费者分别消费了一次、消息共被消费了2次:

检查log:

两个监听方法都接收到了消息。
OK,let’s say it’s a day!
相关文章:
SpringBoot activemq收发消息、配置及原理
SpringBoot集成消息处理框架 Spring framework提供了对JMS和AMQP消息框架的无缝集成,为Spring项目使用消息处理框架提供了极大的便利。 与Spring framework相比,Spring Boot更近了一步,通过auto-configuration机制实现了对jms及amqp主流框架…...
视频智能识别安全帽佩戴系统-工地安全帽佩戴识别算法---豌豆云
视频智能识别安全帽佩戴系统能够从繁杂的工地、煤矿、车间等场景下同时对多个目标是否戴安全帽穿反光衣进行实时识别。 当视频智能识别安全帽佩戴系统发现作业人员没有戴安全帽、穿反光衣或者戴安全带,系统会及时报警提醒,并抓拍存档。 视频智能识别安…...
指针的深入理解(三)
这一节主要使用复习回调函数, 利用冒泡模拟实现qsort函数。 qsort 排序使用冒泡排序,主要难点在于运用元素个数和字节数以及基地址控制元素的比较: if里面使用了一个判断函数,qsort可以排序任意的数据,原因就是因为可…...
【Linux C | 网络编程】详细介绍 “三次握手(建立连接)、四次挥手(终止连接)、TCP状态”
😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀 🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C、数据结构、音视频🍭 🤣本文内容🤣&a…...
主从数据库MySQL服务重启步骤与注意事项
主从数据库MySQL服务重启步骤与注意事项 实验环境: 172.20.26.34 (主应用服务器) 172.20.26.26 (备应用服务器) 172.20.26.37 (主库服务器) 172.20.26.38 (从库服务器&…...
netlink学习
netlink是什么 netlink是Linux内核中的一种进程间通信(IPC)机制。它允许内核空间与用户空间之间,以及用户空间进程之间进行双向通信。 内核里的很多子系统使用netlink通信,包括网络管理(Routing,Netfilt…...
地理空间分析10——空间数据分析中的地理编码与Python
目录 写在开头1. 地理编码基础1.1 地理编码的基本原理1.1.1 坐标系统1.1.2 地名解析1.1.3 编码算法1.2 Python中使用地理编码的基础知识1.2.1 百度地图API1.2.2 高德地图API1.2.3 腾讯地图API1.3 Python中实现代码2. 逆地理编码2.1 利用Python进行逆地理编码2.1.1 获取高德地图…...
使用“快速开始”将数据传输到新的 iPhone 或 iPad
使用“快速开始”将数据传输到新的 iPhone 或 iPad 使用 iPhone 或 iPad 自动设置你的新 iOS 设备。 使用“快速开始”的过程会同时占用两台设备,因此请务必选择在几分钟内都不需要使用当前设备的时候进行设置。 确保你当前的设备已连接到无线局域网,并…...
计算机网络(第六版)复习提纲13
前同步码,七位1010交替出现,帧开始码:10101011 为什么没有帧结束?曼彻斯特码传播完成后,维持高电平,不再跳变,因此不必要设置帧结束。 3.无效的MAC帧 i.数据字段的长度与长度字段的值不一致&…...
[office] excel2010双向条形图制作 #经验分享#微信
excel2010双向条形图制作 本教程为大家介绍一下excel2010中excel2010双向条形图制作方法。 1.选中工作区域 2.点击插入-->图表,选择条形图 3.为美观可将中间竖线可去掉 4.方法是选中竖线,右击-->删除 5.接下来将图例靠上,选中图例,右击-->设置图例格式-->图例选项…...
优雅管理多线程异步任务 - 永动异步任务
引言 在现代应用程序中,经常需要处理长时间运行的异步任务,如消息推送、定时任务等。为了确保这些异步任务能够安全可靠地执行,我们需要一种优雅的管理方式。本文将介绍一种基于线程池的多线程异步任务管理方案,并详细讨论任务的优雅关闭。 1. 多线程异步任务管理的需求 …...
软考笔记--分布式数据库
分布式数据库系统是数据库技术与网络技术相结合的产物,其基本思想是将传统的集中式数据库中的数据分布于网络上的多台计算机中。分布式数据库系统通常使用较小的计算机系统,每台计算机可单独放在一个地方,每台计算机中都有DBMS的一份完整的复…...
vue项目中路由懒加载的三种方式
1 . vue异步组件技术 异步加载 vue-router配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 . 但是,这种情况下一个组件生成一个js文件 /* vue异步组件技术 */ { path: /home, name: home, component: resolve > require([/components/home],resolve) }, { path…...
【制作100个unity游戏之23】实现类似七日杀、森林一样的生存游戏6(附项目源码)
本节最终效果演示 文章目录 本节最终效果演示系列目录前言生命 食物 水简单绘制UI玩家状态脚本生命值控制饱食度控制水分控制 源码完结 系列目录 前言 欢迎来到【制作100个Unity游戏】系列!本系列将引导您一步步学习如何使用Unity开发各种类型的游戏。在这第23篇中…...
Cache Lab:Part A【模拟出使用LRU策略的高速缓存存储器组织结构】
目录 任务描述 知识回顾 实验内容 测试结果 Cache Lab 对应《CS:APP》6.3节至第六章结束的内容。 任务描述 Your job for Part A is to fill in the csim.c file so that it takes the same command line arguments and produces the identical output as the reference …...
操作系统基础:死锁
🌈个人主页:godspeed_lucip 🔥 系列专栏:OS从基础到进阶 🐦1 死锁的概念🦢1.1 总览🦢1.2 什么是死锁🦢1.3 死锁、饥饿、死循环的区别🐧1.3.1 概念🐧1.3.2 区别…...
Ubuntu server如何使用 Daphne + Nginx + supervisor部署 Django
Django从 3.0版开始加入对ASGI的支持,使Django开始具有异步功能。 截止目前的5.0版,对异步支持逐步也越来越好,相信在未来的版本中异步将会支持的更加完善。 所以说,我们也需要适时的更新我们的技能,学会在asgi异步服务器环境中部署django项目! 在部署之前我们所有的依…...
Android 12.0 应用中监听系统收到的通知
1. 需求 在系统内置应用中或者在第三方应用中,获取Android系统收到的通知的内容. 2. NotificationListenerService 接口 Android 系统预留了专门的API, 即 NotificationListenerService 接口,它的源码路径为: 源码路径 : /frameworks/base/core/java/android/service/notifi…...
SpringBoot+Redis如何实现用户输入错误密码后限制登录(含源码)
点击下载《SpringBootRedis如何实现用户输入错误密码后限制登录(含源码)》 1. 引言 在当今的网络环境中,保障用户账户的安全性是非常重要的。为了防止暴力破解和恶意攻击,我们需要在用户尝试登录失败一定次数后限制其登录。这不…...
kotlin中的初始化问题纪录
1. init 代码块的顺序问题 init代码块和成员变量实质上是按先后顺序执行的。若果init{} 中有成员变量使用。要把成员变量放到代码块之前。 2. init代码块之中的函数问题 下面是一段错误的代码: class mkotlin{val info:Stringinit {getInfoMethod()info "adad…...
Java 语言特性(面试系列2)
一、SQL 基础 1. 复杂查询 (1)连接查询(JOIN) 内连接(INNER JOIN):返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...
(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
逻辑回归:给不确定性划界的分类大师
想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&am…...
多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
