Spring源码分析之事件机制——观察者模式(三)

server/2025/1/8 23:42:08/

目录

自定义事件

事件监听器

事件发布者(服务层)

使用示例controller层


Spring源码分析之事件机制——观察者模式(一)-CSDN博客

Spring源码分析之事件机制——观察者模式(二)-CSDN博客

这两篇文章是这个篇章的前篇,感兴趣的读者可以阅读一下,从spring源码分析观察者模式

接下来说明一下Spring事件机制使用案例,就一个模拟用户注册场景的场景吧,事件机制其实还可以运用到更加广泛的作用。

说实话,个人感觉Spring事件机制真的好用。

自定义事件

java">public class UserRegisteredEvent extends ApplicationEvent {private final String username;private final String email;private final LocalDateTime registeredTime;public UserRegisteredEvent(Object source, String username, String email) {super(source);this.username = username;this.email = email;this.registeredTime = LocalDateTime.now();}// getter方法public String getUsername() {return username;}public String getEmail() {return email;}public LocalDateTime getRegisteredTime() {return registeredTime;}
}

事件监听器

java">@Component
@Order(1)  // 定义监听器执行顺序
public class EmailNotificationListener implements ApplicationListener<UserRegisteredEvent> {private final EmailService emailService;@Autowiredpublic EmailNotificationListener(EmailService emailService) {this.emailService = emailService;}@Overridepublic void onApplicationEvent(UserRegisteredEvent event) {// 发送欢迎邮件emailService.sendWelcomeEmail(event.getEmail(), event.getUsername());log.info("Welcome email sent to user: {}", event.getUsername());}
}
java">@Component
@Order(2)
public class UserCacheListener implements ApplicationListener<UserRegisteredEvent> {private final CacheManager cacheManager;@Autowiredpublic UserCacheListener(CacheManager cacheManager) {this.cacheManager = cacheManager;}@Overridepublic void onApplicationEvent(UserRegisteredEvent event) {// 更新用户缓存cacheManager.putUserCache(event.getUsername());log.info("User cache updated for: {}", event.getUsername());}
}

事件发布者(服务层)

java">@Service
@Transactional
public class UserService {private final UserRepository userRepository;private final ApplicationEventPublisher eventPublisher;@Autowiredpublic UserService(UserRepository userRepository, ApplicationEventPublisher eventPublisher) {this.userRepository = userRepository;this.eventPublisher = eventPublisher;}public User registerUser(String username, String email, String password) {// 验证用户数据validateUserData(username, email, password);// 创建用户User user = new User(username, email, password);user = userRepository.save(user);// 发布用户注册事件eventPublisher.publishEvent(new UserRegisteredEvent(this, username, email));log.info("User registered and event published: {}", username);return user;}private void validateUserData(String username, String email, String password) {// 数据验证逻辑}
}

使用示例controller层

java">@RestController
@RequestMapping("/api/users")
public class UserController {private final UserService userService;@Autowiredpublic UserController(UserService userService) {this.userService = userService;}@PostMapping("/register")public ResponseEntity<UserDTO> registerUser(@RequestBody UserRegistrationRequest request) {User user = userService.registerUser(request.getUsername(),request.getEmail(),request.getPassword());return ResponseEntity.ok(UserDTO.fromUser(user));}
}

用户注册时,UserService发布UserRegisteredEvent事件,EmailNotificationListener同步处理邮件发送,UserCacheListener同步更新缓存,AsyncAnalyticsListener异步处理统计数据,通过@Order注解控制监听器执行顺序。

这种实现方式将用户注册的核心逻辑与后续的处理操作解耦,使得系统更容易维护和扩展。每个监听器都专注于自己的职责,可以独立地添加、移除或修改,而不会影响其他部分的代码。


http://www.ppmy.cn/server/155772.html

相关文章

啤酒风味塑造的关键因素——麦汁煮沸

在探索啤酒酿造的工艺过程中&#xff0c;我们发现每一个细微的步骤都对最终的口感和风味产生着不可忽视的影响。今天&#xff0c;让我们深入探讨一个关键环节——麦汁煮沸&#xff0c;以及其中至关重要的概念“煮沸强度”。 何谓煮沸强度&#xff1f;它又如何左右麦汁的品质&a…

Qt之简易音视频播放器设计(十五)

Qt开发 系列文章 - MediaPlayer&#xff08;十五&#xff09; 目录 前言 一、QMediaPlayer 二、实现方式 1.添加multimedia 2.创建类vedioplayer 3.UI设计 4.用户使用 5.效果演示 总结 前言 利用Qt进行音视频播放器设计&#xff0c;首先比较方便使用的是Qt自带的音视…

log4j 单独设置某个类或者某个包的级别

原本的设置 log4j.rootLogger INFO, dailyfilelog4j.appender.dailyfile.DatePattern.yyyy-MM-dd log4j.appender.dailyfile.Threshold INFO log4j.appender.dailyfile org.apache.log4j.DailyRollingFileAppender log4j.appender.dailyfile.File /var/log/zeppelin/zeppe…

基于单片机的俄罗斯方块设计

摘 要:俄罗斯方块游戏是一款风靡全球的经典游戏 。 基于此文章设计了一款基于单片机的俄罗斯方块游戏机,该游戏机可以丰富我们的业余生活。 在硬件设计上该游戏机以 STC89C52 单片机为基础 、 使用 LCD12864 图形液晶可以显示游戏的界面、 通过按键实现游戏机的按钮的功能…

网关的介绍

网关&#xff08;Gateway&#xff09;在网络技术中扮演着举足轻重的角色。为了让你更好地理解网关及其相关术语&#xff0c;我会尽量用简洁明了的语言来解释&#xff0c;同时也会穿插一些专业术语以便你深入学习。 网关的基本概念 网关&#xff0c;顾名思义&#xff0c;是网络的…

计算机网络•自顶向下方法:链路层编址、ARP协议、以太网

链路层编址 MAC地址&#xff08;Media Access Control Address&#xff09;&#xff1a; MAC地址是链路层编址的标准&#xff0c;广泛应用于以太网、Wi-Fi等网络技术。 它是一个48位的地址&#xff0c;通常用12个十六进制数字表示&#xff0c;格式如下&#xff1a; 00:1A:2B…

速通前端篇——JavaScript

找往期文章包括但不限于本期文章中不懂的知识点&#xff1a; 个人主页&#xff1a;我要学编程程(ಥ_ಥ)-CSDN博客 所属专栏&#xff1a;速通前端 目录 介绍 基础语法 创建变量 数据类型 运算符 JavaScript 对象 数组 数组的相关操作 函数 函数表达式 对象 基本…

Effective C++读书笔记——item8(析构函数与异常)

析构函数引发异常的问题 异常同时存在的隐患&#xff1a;C 虽未禁止在析构函数中引发异常&#xff0c;但坚决阻止这样做。以std::vector等容器包含对象为例&#xff0c;当容器析构时要析构其中元素&#xff0c;若在析构元素&#xff08;如Widget类对象&#xff09;过程中连续抛…