⭐⭐⭐ Spring Boot 项目实战 ⭐⭐⭐ Spring Cloud 项目实战
《Dubbo 实现原理与源码解析 —— 精品合集》 《Netty 实现原理与源码解析 —— 精品合集》
《Spring 实现原理与源码解析 —— 精品合集》 《MyBatis 实现原理与源码解析 —— 精品合集》
《Spring MVC 实现原理与源码解析 —— 精品合集》 《数据库实体设计合集》
《Spring Boot 实现原理与源码解析 —— 精品合集》 《Java 面试题 + Java 学习指南》

摘要: 原创出处 blog.csdn.net/qq_35512802/article/details/144314552 「冬天vs不冷」欢迎转载,保留摘要,谢谢!


🙂🙂🙂关注微信公众号:【芋道源码】有福利:

  1. RocketMQ / MyCAT / Sharding-JDBC 所有源码分析文章列表
  2. RocketMQ / MyCAT / Sharding-JDBC 中文注释源码 GitHub 地址
  3. 您对于源码的疑问每条留言都将得到认真回复。甚至不知道如何读源码也可以请教噢。
  4. 新的源码解析文章实时收到通知。每周更新一篇左右。
  5. 认真的源码交流微信群。

前言

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

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

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

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

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

二、发布订阅模式的实现

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

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) {
Object source = event.getSource();
if (source instanceof WebRegistrationService) {
// 处理通过 Web 注册的用户
} else if (source instanceof ApiRegistrationService) {
// 处理通过 API 注册的用户
}
}

三、开发应用场景

1、社交网络平台

用户发布新动态后,动态发布服务触发创建事件。关注者列表服务订阅并推送该动态给关注者,推荐算法服务也订阅事件,分析内容为潜在用户推荐,扩大传播范围。

2、电商系统

商品管理系统修改价格后发布价格变动事件,促销活动系统订阅并重新评估促销规则,购物车系统订阅并实时更新商品价格,确保用户看到最新价格。

3、金融交易系统

用户交易时,交易处理服务发布交易事件,包含金额、类型等信息。账户余额更新系统订阅并更新余额及交易流水,确保准确性和可追溯性。风险监控系统也订阅事件,实时评估风险,检测异常交易并触发预警机制。

总结

Spring的发布-订阅模式通过ApplicationEvent、ApplicationListener和@EventListener等组件,解耦了消息的生产者和消费者,并支持异步通信。这样可以让不同模块独立处理事件,提升系统的灵活性、可扩展性和响应速度。

文章目录
  1. 1. 前言
  2. 2. 一、发布订阅模式的基本概念
  3. 3. 二、发布订阅模式的实现
    1. 3.0.1. 1、定义事件
    2. 3.0.2. 2、发布事件
    3. 3.0.3. 3、订阅事件
  • 4. 三、开发应用场景
    1. 4.0.1. 1、社交网络平台
    2. 4.0.2. 2、电商系统
    3. 4.0.3. 3、金融交易系统
  • 5. 总结