Spring Boot框架强大的事件驱动模型(ApplicationEvent)

devtools/2024/9/22 19:58:08/

文章目录

    • 前言
    • 应用场景
      • 异步处理
      • 事务边界外的操作
      • 跨微服务通信
      • 系统监控与日志聚合
      • UI更新
      • 生命周期管理
      • 工作流或业务流程
      • 缓存同步
    • 小试牛刀
      • 定义事件
      • 实现事件处理器
      • 注册事件处理器
      • 发布事件
      • 测试事件
    • 写在最后

前言

在Spring Boot应用中,事件处理器是指那些处理特定类型事件的对象。SpringBoot框架提供了强大的事件驱动模型(ApplicationEvent),允许应用程序组件之间通过发布和监听事件来进行松耦合的通信。在实际的生产场景中,我们可以使用事件进行缓存、邮件、日志解耦,从而提高系统性能。

应用场景

异步处理

当某个业务操作完成后,需要触发一系列耗时较长的后台任务(如发送邮件通知、更新缓存、清理资源、日志记录等),但又不想阻塞主线程或直接影响用户响应时间。此时,可以通过发布一个事件,由专门的异步事件处理器监听并执行这些任务。

事务边界外的操作

当某个业务操作在一个数据库事务内完成,而后续操作(如更新搜索索引、消息队列投递)需要在事务提交后进行,以避免数据不一致。可以在事务成功提交后发布一个事件,让监听器在事务外部处理这些后续操作。

跨微服务通信

在微服务体系中,不同的服务通常独立部署。当一个服务发生重要状态变更(如订单创建、用户注册、库存更新等)时,可以通过事件机制向其他服务广播事件,使它们能及时响应并更新自身状态,无需直接调用API。这符合“发布-订阅”模式,有助于降低服务间的耦合度。

系统监控与日志聚合

系统中的关键操作或异常情况可以触发特定事件,如性能指标收集、审计日志记录、报警触发等。事件处理器可以统一收集这些事件,将其发送到监控系统、日志平台或报警服务,实现系统的集中监控和日志分析。

UI更新

在Web应用中,尤其是单页应用(SPA)或使用WebSocket等技术实现实时通信的场景,前端界面需要对后端状态变化做出即时响应。后端可以发布事件通知前端更新特定区域的内容,如刷新用户通知列表、显示新消息提示等。

生命周期管理

Spring框架内部及用户自定义组件的生命周期事件也是Event Handler的典型应用场景。例如,Spring容器启动和关闭时会发布相关事件,允许开发者注册监听器来执行初始化配置、资源清理等工作。此外,对于自定义的领域对象,如用户账户的激活、注销等状态变更,也可以通过事件进行通知和处理。

工作流或业务流程

在复杂的业务流程中,如订单审批、文章审核等,每个步骤的完成可以触发事件,促使流程推进到下一个阶段。事件处理器负责检查条件、更新状态,并可能触发新的事件,从而驱动整个流程自动运行。

缓存同步

当主数据发生更改时,如数据库记录的增删改,可以通过事件通知缓存系统更新或失效相应的缓存项,确保数据一致性。
总结来说,Spring Event Handler适用于任何需要在不同组件、服务或层级之间解耦通信、异步处理任务或响应特定状态变更的场景,它有助于构建松耦合、响应式和灵活扩展的系统架构。

小试牛刀

以下是一个Spring Boot事件处理器的示例,我们可以在事件处理其中实现自己想要的逻辑代码。

定义事件

首先,定义一个自定义事件类,它通常继承自ApplicationEvent。例如,假设我们要创建一个表示用户注册成功的事件:

java">import org.springframework.context.ApplicationEvent;/*** UserRegisteredEvent* @author senfel* @version 1.0* @date 2024/4/25 16:38*/
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;}
}

这里,UserRegisteredEvent包含了注册成功的用户名信息。

实现事件处理器

创建一个实现了ApplicationListener接口的类,指定它监听的事件类型。在本例中,我们将创建一个监听UserRegisteredEvent的处理器:

java">import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;/*** UserRegisteredEventHandler* @author senfel* @version 1.0* @date 2024/4/25 16:39*/
@Component
public class UserRegisteredEventHandler implements ApplicationListener<UserRegisteredEvent> {@Overridepublic void onApplicationEvent(UserRegisteredEvent event) {String username = event.getUsername();System.out.println("User registered: " + username);// TODO 具体的业务,这里直接打印完成的信息System.out.println("business action complete: " + username);}
}

onApplicationEvent方法会在接收到匹配类型的事件时被调用。在这个示例中,我们只是简单地打印出已注册用户的用户名,并演示打印缓存结果。

注册事件处理器

由于UserRegisteredEventHandler是一个Spring Bean,只需将其纳入Spring容器管理,它就会自动成为事件监听器。通常,您可以通过@Component注解将其声明为一个Spring Bean,并确保该类所在的包(或指定的包)在Spring Boot主类的@SpringBootApplication注解扫描范围内。

java">import org.springframework.stereotype.Component;@Component
public class UserRegisteredEventHandler implements ApplicationListener<UserRegisteredEvent> {// ...
}

或者,如果您使用Java配置类,可以显式注册该监听器:

java">import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic UserRegisteredEventHandler userRegisteredEventHandler() {return new UserRegisteredEventHandler();}
}

发布事件

当用户注册成功时,在相应的业务逻辑处发布UserRegisteredEvent。通常,您可以在服务层、控制器或其他适当的地方发布事件:

java">import com.example.ccedemo.event.UserRegisteredEvent;
import com.example.ccedemo.service.UserService;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
import org.springframework.stereotype.Service;/*** UserServiceImpl* @author senfel* @version 1.0* @date 2024/4/25 16:45*/
@Service
public class UserServiceImpl implements UserService, ApplicationEventPublisherAware {private ApplicationEventPublisher publisher;@Overridepublic void getUsername(String username) {// 执行注册逻辑...System.out.println("User registered successfully: " + username);// 发布UserRegisteredEventpublisher.publishEvent(new UserRegisteredEvent(this, username));}@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher publisher) {this.publisher = publisher;}
}

上述代码中,UserService实现了ApplicationEventPublisherAware接口,Spring会自动注入ApplicationEventPublisher实例。在registerUser方法中,完成用户注册逻辑后,发布UserRegisteredEvent。此时,UserRegisteredEventHandler会接收到该事件并执行相应的处理逻辑。

测试事件

我们直接新增一个测试类调用获取用户信息方法:

java">import com.example.ccedemo.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;/*** SpringEventTest* @author senfel* @version 1.0* @date 2024/4/25 16:49*/
@SpringBootTest
public class SpringBootEventTest {@Resourceprivate UserService userService;@Testpublic void test(){userService.getUsername("senfel");}
}

在这里插入图片描述

写在最后

总结起来,要创建一个Spring Boot事件处理器,需要:

1、定义一个继承自ApplicationEvent的自定义事件类;
2、实现一个ApplicationListener,指定监听的事件类型,并在onApplicationEvent方法中编写处理逻辑;
3、将事件处理器注册为Spring Bean,使其能自动监听发布的事件;
4、在适当的位置发布事件,通常使用ApplicationEventPublisher。

实际应用中,我们可以根据业务需求定义更多类型的事件和对应的处理器,利用事件驱动模型来解耦组件间的交互。


http://www.ppmy.cn/devtools/22589.html

相关文章

「PHP系列」PHP 过滤器

文章目录 一、PHP过滤器二、PHP函数和过滤器1. 过滤器示例FILTER_VALIDATE_BOOLEANFILTER_VALIDATE_EMAILFILTER_VALIDATE_FLOATFILTER_VALIDATE_INTFILTER_VALIDATE_IPFILTER_VALIDATE_REGEXPFILTER_SANITIZE_STRINGFILTER_SANITIZE_ENCODEDFILTER_SANITIZE_FULL_SPECIAL_CHAR…

二叉树理论和题目

二叉树的种类 在我们解题过程中二叉树有两种主要的形&#xff1a;满二叉树和完全二叉树。 满二叉树 满二叉树&#xff1a;如果一棵二叉树只有度为0的结点和度为 2 的结点&#xff0c;并且度为 0 的结点在同一层上&#xff0c;则这棵二叉树为满二叉树。 这棵二叉树为满二叉树…

常用算法代码模板 (3) :搜索与图论

AcWing算法基础课笔记与常用算法模板 (3) ——搜索与图论 常用算法代码模板 (1) &#xff1a;基础算法 常用算法代码模板 (2) &#xff1a;数据结构 常用算法代码模板 (3) &#xff1a;搜索与图论 常用算法代码模板 (4) &#xff1a;数学知识 文章目录 0 搜索技巧1 树与图的存…

企业如何保证内部传输文件使用的工具是安全的?

企业内部文件的频繁交换成为了日常运营不可或缺的一环。然而&#xff0c;随着数据量的爆炸式增长和网络攻击手段的日益复杂&#xff0c;内网文件传输的安全隐患也日益凸显&#xff0c;成为企业信息安全的薄弱环节。本文将探讨内网文件传输的安全风险、企业常用的防护措施。 内网…

算法学习(5)-图的遍历

目录 什么是深度和广度优先 图的深度优先遍历-城市地图 图的广度优先遍历-最少转机 什么是深度和广度优先 使用深度优先搜索来遍历这个图的过程具体是&#xff1a; 首先从一个未走到过的顶点作为起始顶点&#xff0c; 比如以1号顶点作为起点。沿1号顶点的边去尝试访问其它未…

纯血鸿蒙APP实战开发——评论组件案例实现

介绍 评论组件在目前市面上的短视频app中是一种很常见的场景&#xff0c;本案例使用全局状态保留能力弹窗来实现评论组件。点击评论按钮弹出评论组件&#xff0c;点击空白处隐藏该组件&#xff0c;再次点击评论按钮则会恢复上一次浏览的组件状态。 效果图预览 使用说明 点击…

蓝桥杯单片机省赛——第八届“基于单片机的电子钟程序设计与调试”程序部分

往期回顾 第三届蓝桥杯单片机省赛 第四届蓝桥杯单片机省赛 第五届蓝桥杯单片机省赛 第六届蓝桥杯单片机省赛 第七届蓝桥杯单片机省赛 文章目录 往期回顾一、前期准备二、代码详情1.基础代码蜂鸣器/继电器/led/定时器之类的代码 2.按键详解按键写法讲解 3.驱动的处理驱动写法讲…

Eureka基础知识

Eureka是Netflix开源的一个服务发现框架&#xff0c;主要用于构建基于微服务架构的应用程序。它允许服务实例自动注册和发现&#xff0c;从而实现了服务之间的协调和通信。Eureka的设计目标是简单、可靠和高可用的服务注册和发现。 在微服务架构中&#xff0c;Eureka扮演了两个…