Spring 核心技术解析【纯干货版】- XIII:Spring 消息模块 Spring-Messaging 模块精讲

在现代分布式系统和微服务架构中,消息驱动架构越来越受到关注。Spring Framework 提供了 Spring-Messaging 模块,使得开发者可以使用统一的消息传输抽象,同时支持多种消息协议,如 STOMP、AMQP 和 Kafka。本篇文章将深入解析 Spring-Messaging 模块的核心功能,并通过 WebSocket + STOMP 示例,展示如何使用 Spring 实现高效的实时消息推送。


文章目录

      • 1、Spring-Messaging 模块介绍
        • 1.1、Spring-Messaging 模块概述
        • 1.2、Spring-Messaging 模块依赖
        • 1.3、Spring-Messaging 模块作用
      • 2、基于 Spring-Messaging 的 **WebSocket + STOMP** 示例
        • 2.1、引入 Maven 依赖
        • 2. 2、WebSocket 配置
        • 2.3. WebSocket 消息控制器
        • 2.4、消息模型
        • 2.5、Spring 配置文件(`spring-config.xml`)
        • 2.6、前端 WebSocket 连接(`index.html`)
        • 2.7、启动 Spring 容器
      • X、后记


1、Spring-Messaging 模块介绍

1.1、Spring-Messaging 模块概述

Spring Messaging 模块,是 Spring Framework 的一部分,它为构建基于消息和事件驱动的应用程序提供了基础设施。

Spring Messaging 模块主要关注于消息的抽象处理,支持多种消息传递协议,并且特别强化了对反应式编程模型的支持,使得开发者能更方便地创建高性能、可扩展的分布式系统。

1.2、Spring-Messaging 模块依赖

Spring-Tx 模块的依赖有两个,分别是 Spring-Beans 模块和 Spring-Core 模块。

其中 Spring Beans 模块是对 Spring Bean 进行定义,实现 IOC 基础功能的模块。而 Spring-Core 是 Spring 中的基础模块,它提供了框架运行所必需的核心功能。

1.3、Spring-Messaging 模块作用

Spring-Messaging 的主要作用:

  1. 提供消息传输的抽象:通过 MessageMessageChannelMessageHandler 等抽象,定义了一套标准的消息通信方式,使不同消息系统的使用更加统一。
  2. 支持 STOMP(Simple Text Oriented Messaging Protocol):可用于 WebSocket 的消息推送,例如聊天应用、实时数据更新等。
  3. 集成 Spring Integration:作为 Spring Integration 的一部分,帮助处理企业应用的集成需求,比如基于消息的微服务架构。
  4. 与 Spring AMQP(RabbitMQ)和 Spring Kafka 配合:
    • 提供 @EnableRabbit@RabbitListener 等功能,简化 RabbitMQ 集成。
    • 提供 @KafkaListener 处理 Kafka 消息。
  5. 支持基于消息的事件驱动架构:结合 ApplicationEvent@EventListener,可以在应用内部或分布式环境中进行事件驱动的异步通信。

2、基于 Spring-Messaging 的 WebSocket + STOMP 示例

以下是一个基于 Spring-Messaging 的 WebSocket + STOMP 示例

客户端 通过 WebSocket 发送消息 → 服务器 处理并广播 → 所有订阅者 接收消息,完成一个简单的 实时消息推送 系统。


2.1、引入 Maven 依赖

在 非 Spring Boot 的 Spring 项目中,spring-websocketspring-messaging 需要手动引入:

<dependencies><!-- Spring 核心依赖 --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.39</version> </dependency><!-- Spring Web(提供 WebSocket 支持) --><dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>5.3.39</version></dependency><!-- Spring WebSocket(支持 STOMP) --><dependency><groupId>org.springframework</groupId><artifactId>spring-websocket</artifactId><version>5.3.39</version></dependency><!-- Spring Messaging(提供消息传输的抽象) --><dependency><groupId>org.springframework</groupId><artifactId>spring-messaging</artifactId><version>5.3.39</version></dependency><!-- Jackson(用于消息 JSON 解析) --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.3</version></dependency>
</dependencies>
2. 2、WebSocket 配置

在 非 Spring Boot 项目中,我们需要手动创建 ApplicationContext 并使用 @Configuration 进行配置:

import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;@Configuration
@EnableWebSocketMessageBroker  // 启用 WebSocket 消息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {@Overridepublic void registerStompEndpoints(StompEndpointRegistry registry) {registry.addEndpoint("/ws") // WebSocket 端点.setAllowedOrigins("*") // 允许跨域.withSockJS(); // 兼容 SockJS}@Overridepublic void configureMessageBroker(MessageBrokerRegistry registry) {registry.enableSimpleBroker("/topic"); // 配置消息代理(广播)registry.setApplicationDestinationPrefixes("/app"); // 以 "/app" 为前缀的请求交给控制器处理}
}
2.3. WebSocket 消息控制器
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;@Controller
public class ChatController {@MessageMapping("/chat")  // 监听 "/app/chat"@SendTo("/topic/messages")  // 将消息广播到 "/topic/messages"public MessageDTO sendMessage(MessageDTO message) {System.out.println("Received message from: " + message.getFrom());return new MessageDTO(message.getFrom(), "Replied: " + message.getContent());}
}
2.4、消息模型
public class MessageDTO {private String from;private String content;public MessageDTO() {}public MessageDTO(String from, String content) {this.from = from;this.content = content;}public String getFrom() { return from; }public void setFrom(String from) { this.from = from; }public String getContent() { return content; }public void setContent(String content) { this.content = content; }
}
2.5、Spring 配置文件(spring-config.xml

对于 非 Java 配置 的 Spring 项目,也可以使用 spring-config.xml 进行 Bean 配置:

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:websocket="http://www.springframework.org/schema/websocket"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/websockethttp://www.springframework.org/schema/websocket/spring-websocket.xsd"><!-- 开启组件扫描 --><context:component-scan base-package="com.example.websocket"/><!-- WebSocket 配置 --><websocket:message-broker><websocket:stomp-endpoint path="/ws"><websocket:sockjs/></websocket:stomp-endpoint><websocket:simple-broker prefix="/topic"/><websocket:application-destination-prefixes prefix="/app"/></websocket:message-broker></beans>
2.6、前端 WebSocket 连接(index.html
<script src="https://cdnjs.cloudflare.com/ajax/libs/sockjs-client/1.5.1/sockjs.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stomp.js/2.3.3/stomp.min.js"></script><script>var socket = new SockJS('/ws'); // 连接 WebSocket 端点var stompClient = Stomp.over(socket);stompClient.connect({}, function (frame) {console.log('Connected: ' + frame);// 订阅 "/topic/messages" 以接收服务器推送的消息stompClient.subscribe('/topic/messages', function (message) {var received = JSON.parse(message.body);console.log("Received message: ", received);document.getElementById("messages").innerHTML += "<p><b>" + received.from + ":</b> " + received.content + "</p>";});});function sendMessage() {var from = document.getElementById("name").value;var content = document.getElementById("message").value;stompClient.send("/app/chat", {}, JSON.stringify({from: from, content: content}));}
</script><input type="text" id="name" placeholder="Your Name">
<input type="text" id="message" placeholder="Type a message">
<button onclick="sendMessage()">Send</button>
<div id="messages"></div>
2.7、启动 Spring 容器

纯 Java 配置启动:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class WebSocketApp {public static void main(String[] args) {AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebSocketConfig.class);System.out.println("WebSocket server is running...");}
}

使用 XML 启动:

import org.springframework.context.support.ClassPathXmlApplicationContext;public class WebSocketApp {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");System.out.println("WebSocket server is running...");}
}

X、后记

通过本篇文章,我们深入了解了 Spring-Messaging 模块的核心概念,并基于 WebSocket 和 STOMP 实现了一个简单的实时消息推送系统。Spring-Messaging 不仅简化了消息传输的复杂性,还为分布式应用提供了灵活的事件驱动能力。在实际项目中,结合 RabbitMQ、Kafka 等消息中间件,可以进一步增强系统的可扩展性和稳定性。希望本篇文章能为你的 Spring 开发之旅提供有价值的参考!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/16843.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux第106步_Linux内核RTC驱动实验

1、了解rtc_device结构体 1)、打开“include/linux/rtc.h” rtc_class_ops是需要用户根据所使用的RTC设备编写的,其结构体如下: struct rtc_class_ops { int (*ioctl)(struct device *, unsigned int, unsigned long);/*函数指针ioctl*/ int (*read_time)(struct device *,…

java项目之基于推荐算法的图书购物网站源码(ssm+mybatis+mysql)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于ssm的基于推荐算法的图书购物网站项目。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 项目简介&#xff1a; 基于推荐算法的…

【Antv G2 5.x】饼图添加点击事件,获取当前坐标数据

// 监听 tooltip:show 事件this.chart.on(tooltip:show, (event) => {this.currentShowTooltipName = event.data.items[0].name})// 监听绘图区plot的点击事件this.chart.on(interval:click, ev => {this.$emit(chartClick, this.currentShowTooltipName);})// 监听绘图…

称呼计算器:智能科技,简化您的计算生活

一款手机应用程序&#xff0c;安卓设备上使用。这款计算器应用以其简洁的界面、实用的功能和良好的用户体验而受到用户的喜爱。 计算器的主要特点包括&#xff1a; 基本计算功能&#xff1a;支持加、减、乘、除等基本运算。 科学计算器模式&#xff1a;提供更高级的数学运算功…

STM32 裸机 C编程 vs micropython编程 vs linux python

以led点亮为例。 STM32 裸机 C编程需要设置时钟&#xff0c;管脚。 static void MX_GPIO_Init(void) {GPIO_InitTypeDef GPIO_InitStruct {0};// GPIO端口时钟使能__HAL_RCC_GPIOA_CLK_ENABLE();// 配置PA5为推挽输出模式GPIO_InitStruct.Pin GPIO_PIN_5;GPIO_InitStruct.M…

Spring boot(maven) - Mybatis 超级入门版

前言&#xff1a; 通过实践而发现真理&#xff0c;又通过实践而证实真理和发展真理。从感性认识而能动地发展到理性认识&#xff0c;又从理性认识而能动地指导革命实践&#xff0c;改造主观世界和客观世界。实践、认识、再实践、再认识&#xff0c;这种形式&#xff0c;循环往…

清华大学新闻与传播学院沈阳团队出品的《DeepSeek:从入门到精通》104页PDF

前言 本机运行DeepSeek R1大模型文章如下&#xff1a; Windows电脑本地部署运行DeepSeek R1大模型&#xff08;基于Ollama和Chatbox&#xff09;【保姆级万字教程】在Windows计算机部署DeepSeek大模型&#xff0c;给在实验室无外网的同事们用&#xff08;基于Ollama和OpenWebUI…

kbengine服务器和 数据库 系统路径配置

一、服务器 系统路径配置 二、mysql5.7.44 系统路径配置 mysql 压缩包安装方式 解压压缩包&#xff0c;将解压路径加入 系统环境。 或者 系统变量新增 变量名&#xff1a;MYSQL_HOME 变量值&#xff1a;C:\MyPrograms\mysql-8.0.12-winx64修改系统变量的 path 变量&#xff…

性格测评小程序04题库管理

目录 1 创建数据源1.1 题库表1.2 选项表 2 搭建管理后台2.1 搭建题库功能2.2 搭建选项功能2.3 题库和选项联动 3 最终效果总结 我们现在性格测评的算法是通过40个题目来测评用户属于哪一个分类&#xff0c;为此后台需要有可以设置题目和选项的功能&#xff0c;本篇我们介绍一下…

Navicat导入海量Excel数据到数据库(简易介绍)

目录 前言正文 前言 此处主要作为科普帖进行记录 原先Java处理海量数据的导入时&#xff0c;由于接口超时&#xff0c;数据处理不过来&#xff0c;后续转为Navicat Navicat 是一款功能强大的数据库管理工具&#xff0c;支持多种数据库系统&#xff08;如 MySQL、PostgreSQL、…

sql难点

一、 假设你有一个查询&#xff0c;需要根据 id 是否为 null 来动态生成 SQL 条件&#xff1a; xml复制 <select id"getResources" resultType"Resource">SELECT * FROM resources<where><if test"id ! null">and id <!…

2024年12月中国电子学会青少年软件编程(Python)等级考试试卷(六级)

青少年软件编程&#xff08;Python&#xff09;等级考试试卷&#xff08;六级&#xff09; 一、单选题(共25题&#xff0c;共50分) 1.下面代码的输出结果正确的是?(B) import json json_str [ "Alice", "girl", 17,"New York"] data json.loa…

Qwen2.5-Max:国内新一代 MoE 大模型的崛起!

通义千问 DeepSeek 才火没多久&#xff0c;国内又出现了一款可以比肩 DeepSeek 的 MoE 大模型——Qwen2.5-Max。这款大模型使用了超过 20 万亿 token 的预训练数据及精心设计的后训练方案进行训练&#xff0c;无疑开启了 AI 的新时代。 Qwen2.5-Max Qwen2.5-Max Qwen&#xff0…

把 DeepSeek1.5b 部署在显卡小于4G的电脑上

这里写自定义目录标题 介绍准备安装 Ollama查看CUDA需要版本安装CudaToolkit检查Cuda是否装好二、设置Ollama环境变量三、验证是否跑在GPU上ollama如何导入本地下载的模型安装及配置docker安装open-webui启动open-webui开始对话介绍 Deepseek1.5b能够运行在只用cpu和gpu内存小…

FPGA 28 ,基于 Vivado Verilog 的呼吸灯效果设计与实现( 使用 Vivado Verilog 实现呼吸灯效果 )

目录 前言 一. 设计流程 1.1 需求分析 1.2 方案设计 1.3 PWM解析 二. 实现流程 2.1 确定时间单位和精度 2.2 定义参数和寄存器 2.3 实现计数器逻辑 2.4 控制 LED 状态 三. 整体流程 3.1 全部代码 3.2 代码逻辑 1. 参数定义 2. 分级计数 3. 状态切换 4. LED 输…

日常知识点之面试后反思裸写string类

1&#xff1a;实现一个字符串类。 简单汇总 最简单的方案&#xff0c;使用一个字符串指针&#xff0c;以及实际字符串长度即可。 参考stl的实现&#xff0c;为了提升string的性能&#xff0c;实际上单纯的字符串指针和实际长度是不够了&#xff0c;如上&#xff0c;有优化方案…

用AI绘制CAD气温曲线图

此文章视频讲解地址 https://www.bilibili.com/video/BV1JtKjenEhF 需求 根据气温的JSON数据&#xff0c;用AI自动生成CAD格式的气温曲线DWG图 数据准备 用deepseek获取了北京市最近一个月的气温json数据 AI对话 首先进入唯杰地图云端管理平台 选择与唯杰地图AI对话 需求描…

Web应用项目开发 ——Spring Boot邮件发送

一.邮件发送介绍 邮件发送是一个非常常见的功能&#xff0c;注册时的身份认证、重要通知发送等都会用到邮件发送。在现代的Web应用程序中&#xff0c;邮件发送功能是非常常见且重要的一部分&#xff0c;Spring Boot框架提供了简单且强大的方式来实现邮件发送功能。Spring中提供…

【STM32】通过L496的HAL库Flash建立FatFS文件系统(CubeMX自动配置R0.12C版本)

【STM32】通过L496的HAL库Flash建立FatFS文件系统&#xff08;CubeMX自动配置R0.12C版本&#xff09; 文章目录 FlashFlash地址写Flash地址读 FatFS文件系统配置FatFS移植驱动函数时间戳函数 文件操作函数工作区缓存文件挂载和格式化测试文件读写测试其他文件操作函数 测试附录…

机械臂运动学笔记(一):正向运动学

正向运动学指的是通过相邻关节间的转动和移动坐标&#xff0c;将末端的坐标计算出来。 反向运动学指的是已知机械臂末端的坐标&#xff0c;反算每个关节可能的转动和移动参数。 参考资料&#xff1a;4.机械臂几何法与DH表示法_哔哩哔哩_bilibili 一.任意连杆连接的变量定义&a…