Spring 中的发布-订阅模式
创作时间:
作者:
@小白创作中心
Spring 中的发布-订阅模式
引用
1
来源
1.
https://www.cnblogs.com/pengpengon/p/18144663
发布-订阅模式是一种常见的消息通信模式,在Spring框架中得到了广泛应用。本文将详细介绍Spring中发布-订阅模式的原理和实现方法,并通过一个用户注册的案例来演示具体应用。
发布订阅模式是怎样的?
现在市面上流行的很多消息中间件就是采用的该种模式,这种模式 在实际业务中 将 事件发布者(Publisher) 与 事件订阅者 (Subscriber)通过额外的事件通道(Event Channel)来解耦,其基本原理与先前提到的观察者模式有些许类似,但发布订阅模式额外存在了
Event Channel
的概念,也因此解决了 主题(Subject)和 Observer(观察者)之间的耦合,发布者和订阅者就交互细节上不再需要相互关联,下图可以看到两种模式之间的区别。
在 Spring 中的实际应用
在Spring框架中,发布-订阅模式是通过事件驱动的方式实现的,用于解耦应用程序中的组件。Spring的事件机制允许应用程序中的各个部分以松散耦合的方式进行通信,这种方式在日常编码中最适合应对一些需要状态机的业务模型, 下面就来讲下 在 Spring 中的发布订阅涉及到的概念
- 事件(Event):事件是应用程序中的状态变化或动作,对应于某个特定的行为或状态。在Spring中,事件通常是一个POJO(Plain Old Java Object)类,它包含了与该事件相关的信息。
- 事件发布者(Event Publisher):事件发布者是负责发布事件的组件。在Spring中,ApplicationContext(应用程序上下文)充当了事件发布者的角色。通过ApplicationContext,应用程序可以发布事件,并将其传递给已注册的事件监听器。
- 事件订阅者(Event Subscriber):事件订阅者是负责处理特定类型事件的组件。在Spring中,事件订阅者通常是实现了ApplicationListener接口的类,用于监听并处理发布的事件。
- 事件推送(ApplicationEventPublisher):事件推送是指通过ApplicationEventPublisher接口在Spring中发布事件的过程。这个接口可以在ApplicationContext中使用,用于向已注册的监听器广播事件的发生。
设计步骤
- 定义事件类:首先,定义应用中的各种事件,这些事件可以是任何与应用状态变化或行为相关的事情。事件通常是简单的POJO类。
- 定义发布者:创建事件发布者(Publisher)组件,它负责发布事件。在Spring中,你可以使用ApplicationEventPublisher接口或者直接在Bean方法上标注@EventListener注解来实现。
- 定义订阅者:创建事件订阅者(Subscriber)组件,它负责订阅感兴趣的事件并对事件做出响应。在Spring中,你可以定义实现ApplicationListener接口的类来作为事件监听器,或者使用@EventListener注解在方法上订阅事件。
- 触发事件:在适当的时候,通过发布者发布事件。一旦事件被发布,所有已经注册的订阅者将会收到事件通知并执行相应的逻辑。
这里会以简单的 用户注册的场景来介绍下
Spring ApplicationEventPublisher
的使用方式
定义事件类UserRegisteredEvent
import org.springframework.context.ApplicationEvent;
public class UserRegisteredEvent extends ApplicationEvent {
private final String username;
public UserRegisteredEvent(Object source, String username) {
super(source);
this.username = username;
}
public String getUsername() {
return username;
}
}
创建UserRegistrationService服务,负责注册新用户并发布事件
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;
@Service
public class UserRegistrationService {
@Autowired
private ApplicationEventPublisher eventPublisher;
public void registerUser(String username) {
// 注册新用户逻辑
// ...
// 发布用户注册事件,这里使用 eventPublisher 将 预先定义好的事件交由 Spring 的Event Channel 管理
eventPublisher.publishEvent(new UserRegisteredEvent(this, username));
}
}
创建UserNotificationService服务,订阅UserRegisteredEvent事件并发送通知
@Service
public class UserNotificationService {
@EventListener
public void handleUserRegisteredEvent(UserRegisteredEvent event) {
// 处理用户注册事件,例如发送通知
String username = event.getUsername();
System.out.println("Notification sent for user: " + username);
}
}
创建 Spring 启动类
@SpringBootApplication
@RequiredArgsConstructor
public class Application implements CommandLineRunner {
private final UserRegistrationService userRegistrationService;
public static void main(String[] args) {
SpringApplication app = new SpringApplication(Application.class);
app.setWebApplicationType(WebApplicationType.NONE);
app.run(args);
}
@Override
public void run(String... args) {
// 在启动时注册新用户
userRegistrationService.registerUser("peng");
}
}
最后程序的输出结果 如下所示:
Notification sent for user: peng
案例中的代码已发布在github仓库, 路径为
package com.github.meeting.demo.pattern.pubsub;
热门推荐
这些疼痛症状或是身体的预警信号,“忍忍就过去”并不可取
西班牙内战:一场交织着国际势力的内战
孙权劝学:卿言多务,孰若孤?孤常读书,自以为大有所益。
喝姜粉的功效与作用
吃了辣椒肚子烧的厉害怎么办
虚拟仿真实验教学平台:理论与实践结合,实现数智化、立体化教学
高考一模后冲刺全攻略!青岛名师支招
数字人直播失控怎么办:应对策略与解决方案
虽然都是补气猛将,但西洋参能代替红参、党参能代替人参吗?
心肺复苏按压深度:成人、儿童和婴儿的区别
2月份70城房价数据出炉,广州再提放宽入户条件
研究发现,你所看到的东西可能会扭曲你对时间的感觉
秒懂宏内核、微内核和混合内核的区别
油菜花观赏攻略!解锁大杭州各地限定“黄金海”!
柴造林唢呐制作
是噱头也是生意!和这些艺术家联名做一个火一个
Steam无法启动?排查故障与修复指南
如何优化新能源汽车元EV充电策略以延长电池寿命?
结伴出现的“坏CP”:高血压易引发肾结石,肾结石也会引发高血压!
斯柯达品牌历史:从自行车厂到全球汽车制造商
公司回购股票的原因有哪些?这种行为对公司和股东有什么影响?
如何执行股票回购以优化资本结构?
曹操:文武双全的杰出领袖
罗汉果的营养价值与食用指南
被刻意遗忘的战争:东普鲁士战役,苏德双方两百万人的大会战
高密度海绵床垫好吗? 高密度海绵床垫的优缺点
牛腩,牛肉中肉质带有筋、肉、油花的部分,非常适合慢炖至软烂
三命通会八字口诀精解:掌握命运之钥
水泥的化学成分是什么?
问答型内容优化:FAQ结构化数据实现