Spring Boot 事件驱动:构建灵活可扩展的应用
在 Spring Boot 应用中,事件发布和监听机制是一种强大的工具,它允许不同的组件之间以松耦合的方式进行通信。这种机制不仅可以提高代码的可维护性和可扩展性,还能帮助我们构建更加灵活、响应式的应用。本文将深入探讨 Spring Boot 的事件发布和监听机制,揭示其工作原理,并分享一些最佳实践。
一、观察者模式的应用
Spring Boot的事件发布与监听机制基于观察者模式(Observer Pattern
),这是一种行为设计模式,其中对象之间定义了一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会自动得到通知并更新。具体来说,在Spring Boot中,ApplicationEvent
作为事件对象,而ApplicationListener
则充当事件监听器的角色。每当某个事件发生时,Spring容器会负责通知所有的监听器,使得它们能够根据接收到的信息执行相应的操作。
二、核心概念
- 事件(Event):事件是应用中发生的某个状态变化的信号。在 Spring Boot 中,事件通常是一个继承自 ApplicationEvent 的 Java 对象。事件可以是系统事件(例如,应用启动事件、关闭事件),也可以是自定义事件(例如,用户注册事件、订单创建事件)。
- 事件发布者(Event Publisher):事件发布者负责创建并发布事件。在 Spring Boot 中,通常通过 ApplicationEventPublisher 接口来实现事件的发布。
- 事件监听器(Event Listener):事件监听器负责监听特定的事件,并在事件发生时执行相应的处理逻辑。在 Spring Boot 中,通常通过 @EventListener 注解或者实现 ApplicationListener 接口来实现事件的监听。
三、实现方式
3.1 定义事件
import org.springframework.context.ApplicationEvent;public class MyCustomEvent extends ApplicationEvent {private String message;public MyCustomEvent(Object source, String message) {super(source);this.message = message;}public String getMessage() {return message;}
}
3.2 发布事件
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;@Service
public class MyService {@Autowiredprivate ApplicationEventPublisher publisher;public void doSomething() {//发布事件publisher.publishEvent(new MyCustomEvent(this, "触发自定义事件!"));}
}
3.3 监听事件
这可以通过两种方式实现:
- 实现ApplicationListener接口:这种方式较为传统,需要显式地实现onApplicationEvent()方法。
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class MyEventListener implements ApplicationListener<MyCustomEvent> {@Overridepublic void onApplicationEvent(MyCustomEvent event) {System.out.println("接收到自定义事件: " + event.getMessage());}
}
值得注意的是,对于同步监听器而言,如果希望控制不同监听器之间的执行顺序,则可以使用@Order注解指定优先级。在不同的监听器类上面加上@Order(1)、@Order(2)、@Order(3)…即可
接收到自定义事件1: 触发自定义事件!
接收到自定义事件2: 触发自定义事件!
接收到自定义事件3: 触发自定义事件!
- 使用@EventListener注解:这是更为简洁的做法,只需在目标方法上添加此注解即可。此外,还可以结合@Async注解实现异步监听,但需确保已启用异步支持(例如,在主类或配置类上添加@EnableAsync)。示例代码如下所示:
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;@Component
public class MyEventListener {@EventListener@Async //使用@Async注解,进行异步处理public void handleMyCustomEvent(MyCustomEvent event) {System.out.println("接收到自定义事件: " + event.getMessage());}
}
四、工作原理
-
事件发布:当调用 ApplicationEventPublisher.publishEvent() 方法发布事件时,Spring Boot 会根据事件的类型,将事件发送给所有注册的监听器。如果配置了异步监听,则会在另外的线程处理。
-
事件监听:Spring Boot 会在应用启动时,扫描所有带有 @EventListener 注解的方法或者实现了 ApplicationListener 接口的类,并将它们注册为事件监听器。当事件发生时,Spring Boot 会根据事件类型,调用相应的监听器的方法。监听器方法可以通过参数获取事件对象,并执行相应的处理逻辑。
五、应用场景
- 用户注册:用户注册成功后,发布用户注册事件,触发发送欢迎邮件、短信通知等操作。
- 订单创建:订单创建完成后,发布订单创建事件,触发扣减库存、发送订单通知等操作。
- 日志记录:应用发生异常时,发布异常事件,记录异常信息到日志文件或数据库中。
- 系统监控:应用启动或关闭时,发布启动或关闭事件,用于系统监控。
- 模块解耦:不同模块之间通过事件进行通信,实现模块之间的解耦。
六、高级特性
除了基本的功能外,Spring Boot还提供了其他一些高级特性来丰富事件发布与监听机制的功能性:
- 条件监听:借助SpEL表达式,我们可以为@EventListener设置条件属性,只有当满足指定条件时才会触发监听器。例如,仅当用户的名字为“张三”时才处理用户更新事件。
- 事务感知:通过@TransactionalEventListener注解,可以使监听器的行为与事务状态相关联,默认情况下是在事务提交后执行监听器逻辑。
- 多播器(Multicaster):在内部,Spring使用ApplicationEventMulticaster来管理和分发事件给多个监听器,确保每个监听器都能接收到正确的事件。
七、最佳实践
- 合理定义事件: 事件应该足够细粒度,能够准确描述应用中发生的状态变化。
- 避免过度使用事件:事件机制主要用于处理异步操作,对于同步操作,应该尽量使用直接方法调用。
- 使用事件发布者接口: 为了代码的简洁和清晰,尽量使用ApplicationEventPublisher 接口发布事件,避免手动创建事件对象。
- 避免在事件监听器中执行耗时操作:如果需要在事件监听器中执行耗时操作,应该将其放入单独的线程池中执行,或者使用 @Async 注解进行异步处理。
- 注意事件的传递:如果事件需要在不同的组件之间传递,应该考虑事件的传递效率和安全性。
- 测试: 编写单元测试或集成测试,确保事件发布和监听机制的正确性。
- 异常处理: 在事件监听器中,做好异常处理,避免影响其他业务功能,可以使用try catch 捕获异常,也可以使用@ExceptionHandler 来统一处理异常。
相关文章:

Spring Boot 事件驱动:构建灵活可扩展的应用
在 Spring Boot 应用中,事件发布和监听机制是一种强大的工具,它允许不同的组件之间以松耦合的方式进行通信。这种机制不仅可以提高代码的可维护性和可扩展性,还能帮助我们构建更加灵活、响应式的应用。本文将深入探讨 Spring Boot 的事件发布…...

IM系统设计
读多写少,一般采用写扩散成timeline来做 写扩散模式 利用last message id作为这个作为最后一个消息体 timeline和批量未读和ack 利用ZSET来维护连接的定时心跳,来续约运营商的连接不断开...

华为EC6110T-海思Hi3798MV310_安卓9.0_通刷-强刷固件包
华为EC6110T-海思Hi3798MV310_安卓9.0_通刷-强刷固件包 刷机教程说明: 适用机型:华为EC6110-T、华为EC6110-U、华为EC6110-M 破解总分为两个部分:拆机短接破解(保留IPTV)和OTT卡刷(不保留IPTV)…...

ASP.NET Blazor托管模型有哪些?
今天我们来说说Blazor的三种部署方式,如果大家还不了解Blazor,那么我先简单介绍下Blazor Blazor 是一种 .NET 前端 Web 框架,在单个编程模型中同时支持服务器端呈现和客户端交互性: ● 使用 C# 创建丰富的交互式 UI。 ● 共享使用…...

PyTorch广告点击率预测(CTR)利用深度学习提升广告效果
目录 广告点击率预测问题数据集结构广告点击率预测模型的构建1. 数据集准备2. 构建数据加载器3. 构建深度学习模型4. 训练与评估 总结 广告点击率预测(CTR,Click-Through Rate Prediction)是在线广告领域中的重要任务,它帮助广告平…...

PAT甲级-1017 Queueing at Bank
题目 题目大意 银行有k个窗口,每个窗口只能服务1个人。如果3个窗口已满,就需要等待。给出n个人到达银行的时间和服务时间,要求计算每个人的平均等待时间。如果某个人的到达时间超过17:00:00,则不被服务,等待时间也不计…...

OneData体系架构详解
阿里巴巴的 OneData 体系架构方法论,主要分为三个阶段:业务板块、规范定义 和 模型设计。每个阶段的核心目标是确保数据的高效管理、共享与分析能力。 一. 业务板块(Business Segment) 业务板块是OneData体系架构中的第一步&…...

Gin 框架入门实战系列教程
一,Gin介绍 Gin是一个 Go (Golang) 编写的轻量级 http web 框架,运行速度非常快,如果你是性能和高效的追求者,我们推荐你使用Gin框架。 Gin最擅长的就是Api接口的高并发,如果项目的规模不大,业务相对简单…...

鸿蒙harmony json转对象(2)
在ArkTS(Ark TypeScript)中,接口(interface)是用来定义一个对象的结构,它可以包含属性、方法签名,以及嵌套的类型(包括其他接口或对象类型)。因此,接口里面可…...

M-LAG与E-trunk
M-LAG和E-trunk都是用来实现跨设备链路聚合,解决单点故障的,其大部分特性相同,工作模式M-LAG更胜一筹,支持双活,而且其原理感觉像是vrrpmstp的升级版,是往增加网络可靠性去发展的;而E-trunk是基于LACP扩展实现…...

【面试常见问题】
如何自我介绍 自我介绍是面试关键部分,是面试官了解求职者的首要途径,清晰自信的介绍能提升面试官印象,对求职成功至关重要。 糟糕的自我介绍示例 求职者朱晓明虽表明自己善于交际、积极,23 年毕业且从事 java 开发,…...

Spring Boot Starter介绍
前言 大概10来年以前,当时springboot刚刚出现并没有流行,当时的Java开发者们开发Web应用主要是使用spring整合springmvc或者struts、iBatis、hibernate等开发框架来进行开发。项目里一般有许多xml文件配置,其中配置了很多项目中需要用到的Be…...

vue和reacts数据响应式的差异
Vue 的数据响应式: 原理: Vue 使用 Object.defineProperty 或 Proxy(在 Vue 3 中)来实现数据的响应式。当创建 Vue 实例时,会对 data 对象中的属性进行遍历,将其转换为响应式属性。对于 Object.definePro…...

OpenEuler学习笔记(九):安装 OpenEuler后配置和优化
安装OpenEuler后,可以从系统基础设置、网络配置、性能优化等方面进行配置和优化,以下是具体内容: 系统基础设置 更新系统:以root用户登录系统后,在终端中执行sudo yum update命令,对系统进行更新…...

npm命令与yarn命令的区别
npm与Yarn的区别详解 在软件开发中,npm和Yarn都是流行的包管理工具,它们各自拥有独特的特性和优势。以下是它们的主要区别: 1. 安装速度 npm:安装速度相对较慢,尤其是在依赖项较多的情况下。Yarn:采用并…...

python如何导出数据到excel文件
python导出数据到excel文件的方法: 1、调用Workbook()对象中的add_sheet()方法 wb xlwt.Workbook() ws wb.add_sheet(A Test Sheet) 2、通过add_sheet()方法中的write()函数将数据写入到excel中,然后使用save()函数保存excel文件 ws.write(0, 0, 1234…...

MYSQL学习笔记(五):单行函数(字符串、数学、日期时间、条件判断、信息、加密、进制转换函数)讲解
前言: 学习和使用数据库可以说是程序员必须具备能力,这里将更新关于MYSQL的使用讲解,大概应该会更新30篇,涵盖入门、进阶、高级(一些原理分析);这一篇是讲解单行函数,当然mysql函数很多哈,只有多用才能记得…...

Grafana系列之Dashboard:新增仪表板、新增变量、过滤变量、变量查询、导入仪表板、变量联动、Grafana Alert
概述 关于Prometheus和Grafana的安装,略过。 写在前面 Dashboard:仪表板,可包含多个PanelPanel:面板,Dashboard中的组件 如有写得不对的地方,烦请指出。 新增仪表板 点击右上角的 选择New dashboard…...

(java版本)基于Misty1算法的加密软件的实现-毕业设计
一、基于Misty1算法的加密软件(Java)的实现 随着计算机网络及通信技术的飞速发展,信息安全成了信息社会急需解决的最重要的问题之一,密码技术是保证信息安全的核心技术。本文用JAVA语言开发了一个基于Misty1算法的加密软件&#x…...

Spring注解篇:@RestController详解
全文目录: 开篇语前言摘要概述源码解析使用案例分享代码分析使用场景优缺点分析测试用例 应用场景案例优缺点分析核心类方法介绍测试用例测试用例分析使用场景优缺点分析测试用例 小结总结文末 开篇语 哈喽,各位小伙伴们,你们好呀,…...

C++:将字符数组rkpryyrag,每个字母转换为其前面第13个字母后输出,如果超过a则从z再继续接着数。例如:b前面第1个字母是a。a前面第3个字母是x。
代码如下: #include <iostream> #include <string> using namespace std;int main(){string str "rkpryyrag";for (int i 0; i < str.length(); i){if (str[i] > a && str[i] < z){if (str[i] - a < 13){cout <<…...

《探秘鸿蒙Next:人工智能助力元宇宙高效渲染新征程》
在元宇宙的宏大愿景中,高效的渲染技术是构建沉浸式虚拟世界的关键。鸿蒙Next凭借与人工智能的深度融合,为元宇宙的渲染带来了全新的解决方案和无限可能。 智能场景分析与优化 人工智能能够对元宇宙场景进行智能分析。鸿蒙Next可以利用AI技术对场景中的…...

微前端qiankun的部署
微前端qiankun的部署 本地开发主应用配置启动端口子应用配置启动端口测试环境部署:场景 1:主应用和微应用部署到同一个服务器(同一个 IP 和端口)微应用都放在在一个特殊名称(不会和微应用重名)的文件夹下主应用配置子应用配置配置nginx本地开发 主应用配置启动端口 打开…...

HTML表格-掌握表格标签与属性
HTML表格是网页设计中用于展示数据的强大工具,它通过一系列标签和属性来控制表格的布局和样式。 一、HTML表格的基本结构 HTML表格由<table>标签定义,内部包含多个行(<tr>)、单元格(<td>或<th&…...

PID控制的优势与LabVIEW应用
PID控制(比例-积分-微分控制)已在工业控制领域得到广泛应用,尤其在实时控制和自动化系统中,其核心优点是简单、稳定且高效。尽管许多现代控制方法(如自适应控制、模型预测控制等)逐渐崭露头角,P…...

全球化趋势与中资企业出海背景
1. 全球化趋势与中资企业出海背景 1.1 全球经济格局变化 全球经济格局正经历深刻变革,新兴经济体崛起,全球产业链重塑,中资企业出海面临新机遇与挑战。据世界银行数据,新兴市场和发展中经济体在全球 GDP 中占比已超 40%ÿ…...

Oracle之RMAN备份异机恢复(单机到单机)
Oracle之RMAN备份异机恢复(单机到单机) 一、环境说明二、正式库进行RMAN备份三、将正式库备份与参数文件拷贝到测试库四、测试库异机恢复五、验证数据 一、环境说明 系统版本主机名DB版本DB名实例名Public-IP正式库Redhat9.5lemonEnterprise 19.25lemon…...

Servlet快速入门
Servlet 由于目前主流使用SpringBoot进行开发Servlet可以说是时代的眼泪,这篇文章主要介绍我基于SpringBoot对应Servlet的浅薄认知,有利于更好的理解前端界面和java服务器的数据交换过程 快速入门 我比较推荐这篇文章来对Servlet有一个大概的了解 都2…...

深入解析 Linux 内核中的 InfiniBand 驱动接口:ib_verbs.h
InfiniBand(IB)是一种高性能、低延迟的网络互连技术,广泛应用于高性能计算(HPC)、数据中心和云计算等领域。Linux 内核通过 InfiniBand 子系统提供了对 IB 设备的支持,而 ib_verbs.h 是 InfiniBand 驱动开发中的核心头文件之一。它定义了 IB 核心框架与用户空间接口(ver…...

vulnhub靶场【kioptrix-1靶机】
前言 靶机:kioptrix-1,IP地址为192.168.1.104 攻击:kali,IP地址为192.168.1.16 都采用虚拟机,网卡为桥接模式 文章中涉及的靶机,来源于vulnhub官网,想要下载,可自行访问官网下载&…...