专栏名称: Java基基
一个苦练基本功的 Java 公众号,所以取名 Java 基基
目录
相关文章推荐
51好读  ›  专栏  ›  Java基基

Spring发布-订阅模式:解耦与异步通信的高效实现

Java基基  · 公众号  ·  · 2025-01-25 16:58

正文

👉 这是一个或许对你有用 的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入 芋道快速开发平台 知识星球。 下面是星球提供的部分资料:

👉 这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、 商城 、支付、工作流、大屏报表、微信公众号、 ERP CRM AI 大模型 等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本

来源:blog.csdn.net/qq_35512802
/article/details/144314552


前言

Spring框架通过发布订阅模式为组件间通信提供了高效且松散耦合的解决方案,提升了系统的灵活性和扩展性。

本文将探讨该模式的原理、实现、应用场景及其优势与挑战。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

一、发布订阅模式的基本概念

发布订阅模式,又称为观察者模式( Observer Pattern )的一种变体,是一种基于消息传递的设计模式。在这个模式中,主要涉及三个核心角色: 发布者( Publisher 订阅者( Subscriber 消息代理( Message Broker

  • 发布者是消息的产生者 ,它负责生成特定类型的消息并将其发送到消息代理。发布者不需要了解有哪些订阅者对其发布的消息感兴趣,它只专注于消息的生成和发布。
  • 订阅者则是对特定类型消息感兴趣的组件 ,它们向消息代理注册自己感兴趣的消息类型。当消息代理接收到发布者发送的符合订阅者兴趣的消息时,会将消息转发给对应的订阅者。订阅者可以根据接收到的消息进行相应的业务处理。
  • 消息代理是发布者和订阅者之间的中介 ,它负责接收发布者的消息,并根据订阅者的注册信息将消息分发给相应的订阅者。消息代理的存在使得发布者和订阅者之间实现了高度的解耦,它们不需要直接相互引用或通信,只需要与消息代理进行交互即可。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

二、发布订阅模式的实现

下面通过发布订阅模式实现一个示例:在用户注册成功后,系统自动发送邮件通知用户。

1、定义事件

定义事件类,事件类通常继承自 org.springframework.context.ApplicationEvent

我们可以定义一个 UserRegisteredEvent 类来表示用户注册成功的事件

public class UserRegisteredEvent extends ApplicationEvent {
 // 这里的User是一个包含用户相关信息的实体类
    private User user;
 
 // source:事件的源对象,用于表明这个事件是由哪个对象触发的
 // 具体作用下面订阅事件中解释
    public UserRegisteredEvent(Object source, User user) {
        super(source);
        this.user = user;
    }

    public User getUser() {
        return user;
    }
}

2、发布事件

发布事件的组件需要获取 ApplicationEventPublisher 实例,并通过它来发布事件

在用户注册操作成功完成后,发布用户注册事件

@Service
public class UserRegistrationService {
    @Autowired
    private ApplicationEventPublisher eventPublisher;

    public void registerUser(User user) {
        // 执行用户注册逻辑,如保存用户信息到数据库等

        // 注册成功后发布事件
        UserRegisteredEvent event = new UserRegisteredEvent(this, user);
        eventPublisher.publishEvent(event);
    }
}

3、订阅事件

3.1、ApplicationListener接口

订阅者可以通过实现 org.springframework.context.ApplicationListener 接口来订阅特定的事件

发送欢迎邮件的服务可以订阅 UserRegisteredEvent 事件

@Component
public class WelcomeEmailSender implements ApplicationListener<UserRegisteredEvent{
    @Override
    public void onApplicationEvent(UserRegisteredEvent event) {
        User user = event.getUser();
        // 发送欢迎邮件给用户的逻辑,如调用邮件发送接口等
        System.out.println("Sending welcome email to " + user.getEmail());
    }
}

3.2、@EventListener注解

除了基于接口的订阅方式,Spring还提供了 @EventListener 注解来简化订阅者的实现。

Spring还提供了对异步事件的支持,可以使用@Async注解来实现异步处理,从而避免阻塞事件的发布者

@Component
public class AnotherWelcomeEmailSender {
    @EventListener
    @Async
    public void handleUserRegisteredEvent(UserRegisteredEvent event) {
        User user = event.getUser();
        // 发送欢迎邮件的逻辑
        System.out.println("Another welcome email sent to " + user.getEmail());
    }
}

3.3、事件源Object source的作用

假设有一个Web服务和一个API服务都可能触发 UserRegisteredEvent 事件,你可以在监听器中根据source进一步区分事件的处理方式

@EventListener
public void onUserRegistered(UserRegisteredEvent event)






请到「今天看啥」查看全文