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 {

    @Override
    public void registerStompEndpoints(StompEndpointRegistry registry) {
        registry.addEndpoint("/ws") // WebSocket 端点
                .setAllowedOrigins("*") // 允许跨域
                .withSockJS(); // 兼容 SockJS
    }

    @Override
    public 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/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/websocket
           http://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 开发之旅提供有价值的参考!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

实现限制同一个账号最多只能在3个客户端(有电脑、手机等)登录(附关键源码)

如上图&#xff0c;我的百度网盘已登录设备列表&#xff0c;有一个手机&#xff0c;2个windows客户端。手机设备有型号、最后登录时间、IP等。windows客户端信息有最后登录时间、操作系统类型、IP地址等。这些具体是如何实现的&#xff1f;下面分别给出android APP中采集手机信…

如何获取,CPU,GPU,硬盘,网卡,内存等硬件性能监控与各项温度传感器

首先需要下载 OpenHardwareMonitorServer 这是一个基于OpenHardwareMonitor 的 Web 服务器。可以让任何语言都可以获取硬件信息和值&#xff0c;OpenHardwareMonitorServer 是没有UI界面的因此它可以当成控制台程序使用。 该程序可用参数如下 参数&#xff1a;需要管理员权限…

解锁大语言模型潜能:KITE 提示词框架全解析

大语言模型的应用日益广泛。然而&#xff0c;如何确保这些模型生成的内容在AI原生应用中符合预期&#xff0c;仍是一个需要不断探索的问题。以下内容来自于《AI 原生应用开发&#xff1a;提示工程原理与实战》一书&#xff08;京东图书&#xff1a;https://item.jd.com/1013604…

C++STL容器之map的使用及复现

map 1. 关联式容器 vector、list、deque、forward_list(C11) 等STL容器&#xff0c;其底层为线性序列的数据结构&#xff0c;里面存储的是元素本身&#xff0c;这样的容器被统称为序列式容器。而 map、set 是一种关联式容器&#xff0c;关联式容器也是用来存储数据的&#xf…

网络工程师 (30)以太网技术

一、起源与发展 以太网技术起源于20世纪70年代&#xff0c;最初由Xerox公司的帕洛阿尔托研究中心&#xff08;PARC&#xff09;开发。最初的以太网采用同轴电缆作为传输介质&#xff0c;数据传输速率为2.94Mbps&#xff08;后发展为10Mbps&#xff09;&#xff0c;主要用于解决…

30天开发操作系统 第 20 天 -- API

前言 大家早上好&#xff0c;今天我们继续努力哦。 昨天我们已经实现了应用程序的运行, 今天我们来实现由应用程序对操作系统功能的调用(即API, 也叫系统调用)。 为什么这样的功能称为“系统调用”(system call)呢&#xff1f;因为它是由应用程序来调用(操作)系统中的功能来完…

Java面试题及答案整理( 2023年 6 月最新版,持续更新)

秋招金九银十快到了&#xff0c;发现网上很多Java面试题都没有答案&#xff0c;所以花了很长时间搜集整理出来了这套Java面试题大全~ 这套互联网 Java 工程师面试题包括了&#xff1a;MyBatis、ZK、Dubbo、EL、Redis、MySQL、并发编程、Java面试、Spring、微服务、Linux、Spri…

查询语句来提取 detail 字段中包含 xxx 的 URL 里的 commodity/ 后面的数字串

您可以使用以下 SQL 查询语句来提取 detail 字段中包含 oss.kxlist.com 的 URL 里的 commodity/ 后面的数字串&#xff1a; <p><img style"max-width:100%;" src"https://oss.kxlist.com//8a989a0c55e4a7900155e7fd7971000b/commodity/20170925/20170…

管式超滤膜分离技术都可以应用到哪些行业?

管式超滤膜分离技术由于其高效、稳定和适应性强的特点&#xff0c;在多个行业都有广泛的应用&#xff1a; 1. 生物制药与医药行业 纯化与浓缩&#xff1a;在生物药品的下游处理阶段&#xff0c;管式超滤膜被用来纯化抗体、疫苗、蛋白质等生物大分子&#xff0c;通过精确筛选分子…

基于opencv的 24色卡IQA评测算法源码-可完全替代Imatest

1.概要 利用24色卡可以很快的分析到曝光误差&#xff0c;白平衡误差&#xff0c;噪声&#xff0c;色差&#xff0c;饱和度&#xff0c;gamma值。IQA或tuning工程一般用Imatest来手动计算&#xff0c;不便于产测部署&#xff0c;现利用opencv实现了imatest的全部功能&#xff0c…

【matlab优化算法-17期】基于DBO算法的微电网多目标优化调度

基于蜣螂DBO算法的微电网多目标优化调度 一、前言 微电网作为智能电网的重要组成部分&#xff0c;其优化调度对于降低能耗、减少环境污染具有重要意义。本文介绍了一个基于Dung Beetle Optimizer&#xff08;DBO&#xff09;算法的微电网多目标优化调度项目&#xff0c;旨在通…

【多模态大模型】系列2:Transformer Encoder-Decoder——BLIP、CoCa、BEITv3

目录 1 BLIP2 CoCa3 BEITv3 1 BLIP BLIP: Bootstrapping Language-Image Pre-training for Unified Vision-Language Understanding and Generation BLIP是 ALBEF 原班人马做的&#xff0c;基本可以看做吸收了 VLMo 思想的 ALBEF。训练的 loss 和技巧都与 ALBEF一致&#xff…

算法——搜索算法:原理、类型与实战应用

搜索算法&#xff1a;开启高效信息检索的钥匙 在信息爆炸的时代&#xff0c;搜索算法无疑是计算机科学领域中熠熠生辉的存在&#xff0c;它就像一把神奇的钥匙&#xff0c;为我们打开了高效信息检索的大门。无论是在日常生活中&#xff0c;还是在专业的工作场景里&#xff0c;…

在vmd中如何渲染透明水分子

1.设置背景为白色 依次点击Graphics>>Colors... 2. 改变渲染模式 依次点击Display>>rendermode>>GLSL 3. 渲染水分子 选中水分子&#xff0c;显色方式改为ColorID, 编号10的颜色&#xff1b; 选择材质为GlassBubble; 绘图方式为QuickSurf. 若水盒子显示效…

【Cocos TypeScript 零基础 15.1】

目录 见缝插针UI脚本针脚本球脚本心得_旋转心得_更改父节点心得_缓动动画成品展示图 见缝插针 本人只是看了老师的大纲,中途不明白不会的时候再去看的视频 所以代码可能与老师代码有出入 SIKI_学院_点击跳转 UI脚本 import { _decorator, Camera, color, Component, directo…

Go+Wails+Vue 开发:添加停止按钮功能的实现

在本教程中&#xff0c;我将展示如何在一个使用 Wails 框架&#xff08;后端 Go&#xff09;和 Vue.js&#xff08;前端&#xff09;的彩票模拟器项目中添加一个“停止”按钮。由于现有的教程内容较为单一&#xff0c;我将通过具体的实现步骤进行详细说明。 项目初始化 首先&a…

微服务保护---Sentinel

1. 初始Sentinel 1.1. 雪崩问题及解决方案 1.1.1. 雪崩问题 微服务中&#xff0c;服务间调用关系错综复杂&#xff0c;一个微服务往往依赖于多个其它微服务。 如图&#xff0c;如果服务提供者I发生了故障&#xff0c;当前的应用的部分业务因为依赖于服务I&#xff0c;因此也会…

win32汇编环境,窗口程序使用跟踪条(滑块)控件示例一

;运行效果 ;win32汇编环境,窗口程序使用跟踪条(滑块)控件示例一 ;生成2条横的跟踪条,分别设置不同的数值范围,设置不同的进度副度的例子 ;直接抄进RadAsm可编译运行。重要部分加备注。 ;下面为asm文件 ;>>>>>>>>>>>>>>>>>…

pnpm的使用

pnpm的使用 1.安装和使用2.统一包管理工具下载依赖 1.安装和使用 pnpm:performant npm &#xff0c;意味“高性能的npm”。 pnpm由npm/yarn衍生而来,解决了npm/yarn内部潜在的bug,极大的优化了性能,扩展了使用场景。被誉为“最先进的包管理工具”。 pnpm安装指令: npm i -g p…

音视频协议

1. 多媒体信息 1.1 多媒体信息的两个主要特点&#xff1a; 信息量很大 标准语音&#xff1a;64Kbits(8KHz采样&#xff0c;8位编码)高质量音频&#xff1a;3Mbps(100KHz采样&#xff0c;12位编码) 在传输多媒体数据时&#xff0c;对时延和时延抖动均有较高要求 1.2 处理时延…