探索Spring事件监听机制的奇妙世界
文章目录
- 什么是Spring事件监听机制
- 主要组件
- 内置的事件监听类
- 自定义事件监听类
- 总结
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。
什么是Spring事件监听机制
Spring事件监听机制是Spring框架中的一种设计模式,主要用于处理应用程序的各种事件。这种机制基于发布-订阅设计模式,允许将业务逻辑解耦,并能更好地组织和管理代码。
使用 Spring 事件监听机制的好处:
- 解耦:通过将事件的响应逻辑交给监听器处理,可以将事件源和监听器解耦,降低代码的耦合度。
- 可扩展性:可以添加新的监听器来处理新的事件类型,而无需修改原有代码。
- 可重用性:相同类型的事件可以在多个地方处理,提高了代码的可重用性。
- 异步处理:事件监听机制支持异步处理,可以避免阻塞主线程,提高应用程序的性能。
- 事件过滤:可以使用条件筛选需要处理的事件,只对符合条件的事件进行处理。
主要组件
Spring 事件监听机制包括以下几个主要组件:
- 事件源(Event Source):事件源是事件的发起者,通常是一个应用程序中的特定组件或服务。当事件源发生特定事件时,会触发事件的发布。
- 事件(Event):事件是事件源发出的消息,通常包含与事件相关的数据。事件可以是自定义的类,继承自 Spring 的
ApplicationEvent类。 - 监听器(Listener):监听器是订阅了事件源的事件并负责处理事件的组件。监听器需要实现 Spring 的
ApplicationListener接口,并指定要监听的事件类型,该接口定义了一个onApplicationEvent方法,用于处理接收到的事件。。 - 发布者(Publisher):发布者是负责将事件发布给所有注册的监听器的组件。在 Spring 框架中,可以使用
ApplicationContext的 publishEvent 方法来发布事件。 - 应用上下文(ApplicationContext):
ApplicationContext是Spring中的一个中心类,它提供了一个将事件发布到监听器的机制。
内置的事件监听类
Spring框架提供了许多内置的事件监听类,用于处理不同的事件。以下是一些常用的Spring事件监听类:
-
ContextRefreshedEvent:当ApplicationContext被初始化或刷新时触发。可以用来执行在应用程序启动后需要进行的初始化任务。
-
ContextStartedEvent:当ApplicationContext被启动(调用start()方法)时触发。可以用来执行在应用程序启动后需要进行的特定任务。
-
ContextStoppedEvent:当ApplicationContext被停止(调用stop()方法)时触发。可以用来执行在应用程序停止前需要进行的清理任务。
-
ContextClosedEvent:当ApplicationContext被关闭(调用close()方法)时触发。可以用来执行在应用程序关闭前需要进行的清理任务。
-
RequestHandledEvent:当一个HTTP请求被处理完成后触发。可以用来记录请求的处理信息或进行其他相关操作。
这些只是一些常见的事件监听类,实际上Spring还提供了更多的事件监听类,可以满足不同场景下的需求。开发者也可以自定义事件监听类,继承自ApplicationEvent,以实现自己的特定事件监听逻辑。

自定义事件监听类
自定义事件监听类之前 先来了解一下Spring事件监听机制的基本工作流程:
- 定义事件:事件通常是扩展ApplicationEvent的类的对象,它包含有关事件的信息。
- 定义监听器:监听器是实现了ApplicationListener接口的类,被定义为处理特定事件类型的类。
- 注册监听器:通过将监听器注册到Spring容器中,或者手动添加到ApplicationContext中。
- 发布事件:在需要的情况下,通过调用ApplicationContext的
publishEvent()方法发布事件,Spring将该事件传递给所有匹配的监听器。
Spring机制基于发布-订阅设计模式,这就像你关注了某个人,他一旦有作品更新,你就能立马收到消息一样。
下面举个例子自定义一个Spring事件监听功能,比如你喜欢波多老师并且关注了她,波多老师一旦发布新电影你就能收到并且观看。具体代码如下:
- 定义事件MovieEvent
public class MovieEvent extends ApplicationEvent {private String movieName;public MovieEvent(Actor source , String movieName) {super(source);this.movieName = movieName;}public String getMovieName() {return movieName;}
}
@Data
public class Actor {private String name;}
- 定义监听器MovieListener
定义监听器有两种方式,一是实现 ApplicationListener接口,而是使用 @EventListener 注解。下面使用这两种方式分别定义一个监听器。
@Component
public class MovieListener implements ApplicationListener<MovieEvent> {@Overridepublic void onApplicationEvent(MovieEvent event) {Actor actor = (Actor) event.getSource();String movieName = event.getMovieName();System.out.println("实现类监听器 监听到"+actor.getName()+" 发布了新电影,电影名字叫:"+movieName);}
}
@Component
public class MovieListener2 {@EventListenerpublic void listener(MovieEvent event) {Actor actor = (Actor) event.getSource();String movieName = event.getMovieName();System.out.println("注解监听器 监听到 "+actor.getName()+" 发布了新电影,电影名字叫:"+movieName);}
}
@EventListener注解是方法级别的注解,使用它可以在一个类中定义多个监听方法。
- 测试事件发布功能
@RunWith(SpringRunner.class)
@SpringBootTest(classes = MqApplication.class)
public class RestTest {@Autowiredprivate ApplicationEventPublisher applicationEventPublisher;@Autowiredprivate ApplicationContext applicationContext;@Testpublic void testEvent(){Actor boDuo = new Actor();boDuo.setName("波多老师");MovieEvent movieEvent = new MovieEvent(boDuo , "好好学习,别胡思乱想!");applicationContext.publishEvent(movieEvent);}
}
测试结果:
实现类监听器 监听到波多老师 发布了新电影,电影名字叫:好好学习,别胡思乱想!
注解监听器 监听到 波多老师 发布了新电影,电影名字叫:好好学习,别胡思乱想!
ApplicationContext 继承了 ApplicationEventPublisher ,所以发布事件既可以通过 ApplicationEventPublisher#publishEvent() 方法,也可以通过ApplicationContext#publishEvent() 方法。
通过上面的测试结果可以发现,两个监听类最终都监听到了MovieEvent ,都在控制台打印结果了。
实际上Spring的事件监听机制对于同一个事件的监听是同步的,默认情况下是同步的。当事件被发布时,Spring会依次通知所有监听该事件的监听器,并在事件发布的同一线程中依序执行监听器的处理逻辑。
这意味着,当一个事件被触发后,事件监听器的执行是按照注册的顺序依次进行的,前一个监听器完成后才会执行下一个监听器。只有当所有监听器都执行完毕后,事件发布者才会继续往下执行。
如果想实现异步可以在监听器的方法上添加@Async注解,或在配置文件中进行相应的配置,可以使监听器的处理逻辑在不同的线程中执行,从而实现异步处理。
如果是想实现监听器按照指定顺序执行,可以使用 @Order 注解,@Order注解的值越小,优先级越高,即执行顺序越靠前。
总结
总的来说,Spring事件监听机制使用起来简单方便,可以是组件之间解耦,提高了代码的可维护性和可扩展性。当需要使用监听机制的时候,Spring的事件监听机制是个很好的选择之一。
相关文章:
探索Spring事件监听机制的奇妙世界
文章目录 什么是Spring事件监听机制主要组件内置的事件监听类自定义事件监听类总结 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 什么是Spring事件监听机制 Spring事件监听机制是Spr…...
什么是散列函数
散列函数是一种公开的数学函数。散列函数运算的输入信息也可叫作报文。散列函数运算后所得到的结果叫作散列码或者叫作消息摘要。散列函数具有如下一些特点: (1)不同内容的报文具有不同的散列码,而一旦原始报文有任何改变…...
tomcat反序列化
漏洞介绍: 漏洞名称: Apache Tomcat反序列化漏洞影响范围: Apache Tomcat服务器中使用了自带session同步功能的配置,且没有使用Encrypt Interceptor加密拦截器的情况下。漏洞描述: Apache Tomcat是一个基于Java的Web应用软件容器,用于运行servlet和JSP Web应用。当Tomc…...
flask 请求勾子实现 request_auth认证
from flask import g,request from comment.utils.tokens_pyjwt import verify_tokensdef jwt_request_auth():从请求(request)中获取token,并且验证token,验证成功之后把用户id保存到全局变量g中g.user_idNone #定义变量#前端代码是是把token携带请求头…...
【STM32入门】3.OLED屏幕
1.OLED引脚 OLED屏幕的接线按图所示,本例中用的是4管脚OLED屏幕 2.驱动程序 配套的驱动程序是“OLED.c",主要由以下函数构成:1、初始化;2、清屏;3、显示字符;4、显示字符串;5、显示数字…...
python圣诞树代码编程
以下是一个简单的Python圣诞树代码: def draw_tree(height): for i in range(height): print( * (height - i - 1) * * (2 * i 1)) print( * (height - 1) |)draw_tree(10) 这个函数会绘制一个等腰三角形,其中每一行的星号数量从1开…...
js数组删除某个元素
...
hbuilder + uniapp +vue3 开发微信云小程序
1、创建项目: 2、创建项目完成的默认目录结构: 3、在根目录新建一个文件夹cloudFns(文件名字随便),存放云函数源码: 4、修改manifest.json文件:添加 小程序 appid和cloudfunctionRoot࿰…...
服务器配置免密SSH
在当今互联网时代,远程工作和网络安全已成为信息技术领域的热点话题。无论是管理远程服务器、维护网络设备还是简单地从家中连接到办公室,安全始终是首要考虑的因素。这就是为什么 SSH(Secure Shell)成为了网络专业人士的首选工具…...
2023 开发人员生态系统现状信息图:《开发者生态系统现状报告》
本心、输入输出、结果 文章目录 2023 开发人员生态系统现状信息图:《开发者生态系统现状报告》前言目录细节软件开发者薪资趋势过去 3 年科技行业的性别分布 生成式 AI 服务的复杂格局开发者社区的心理健康花有重开日,人无再少年实践是检验真理的唯一标准…...
TCP协议实现一对一聊天
服务端代码: import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; /** * 发送消息线程 */ class…...
python使用conda管理多个环境
一、Anaconda简介 Anaconda 是专门为了方便使用 Python 进行数据科学研究而建立的一组软件包,涵盖了数据科学领域常见的 Python 库,并且自带了专门用来解决软件环境依赖问题的 conda 包管理系统。主要是提供了包管理与环境管理的功能,可以很方…...
实现个微机器人的二次开发
请求URL: http://域名地址/scanJoinRoom 请求方式: POST 请求头Headers: Content-Type:application/jsonAuthorization:login接口返回 参数: 参数名必选类型说明wId是string登录实例标识url是string…...
Android 记录一些Framework开发的命令
源码编译流程 1. "source build/envsetup.sh" (source可以用 . 代替,即". build/envsetup.sh") 2. "lunch",并选择要编译的项目或者"choosecombo" 3. "make idegen -j4" (这里的 -j4 表示用4线程来…...
Ant Design Vue 年选择器
文章目录 参考文档效果展示实现过程 参考文档 提示:这里可以添加本文要记录的大概内容: DatePicker 日期选择框 大佬:搬砖小匠(Ant Design vue 只选择年) 提示:以下是本篇文章正文内容,下面案…...
AGM CPLD 应用指南
AGM的部分料号跟Altera 硬件Pin to Pin兼容,映射关系表如下: EPM240T100CxN—>AG256SL100(CPLD) EPM240T100IxN---->AG256SL100(CPLD) EPM570T100CxN—>AG576SL100(CPLD) EPM570T100IxN---->AG576SL100(CPLD) EPM570T144CxN—>AG576SL144…...
(1)词法分析器
简单来说就是写一个函数,这个函数的输入是文字流,我们要把这个文字流的标签搞出来 比如某种语言标签如下 enum Token {tok_eof -1,// commandstok_def -2,tok_extern -3,// primarytok_identifier -4,tok_number -5, }; 然后词法分析器相当于一个…...
丢掉破解版,官方免费了!!!
哈喽!大家好。 几天不见,今天给大家带来一款海外的神器,官方宣布完全免费,但仅限于个人与教育用途,切勿商用噢! 不要看这个软件名字普普通通,实际上内蕴乾坤! 接下来看我给大家炫一…...
Termux
touch myfile.txt termux-setup-storage 访问手机文件 参考地址 apt update apt upgrade 命令参考链接...
yolo目标检测+目标跟踪+车辆计数+车辆分割+车道线变更检测+速度估计
这个项目使用YOLO进行车辆检测,使用SORT(简单在线实时跟踪器)进行车辆跟踪。该项目实现了以下任务: 车辆计数车道分割车道变更检测速度估计将所有这些详细信息转储到CSV文件中 车辆计数是指在道路上安装相应设备,通过…...
Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
Redis的发布订阅模式与专业的 MQ(如 Kafka, RabbitMQ)相比,优缺点是什么?适用于哪些场景?
Redis 的发布订阅(Pub/Sub)模式与专业的 MQ(Message Queue)如 Kafka、RabbitMQ 进行比较,核心的权衡点在于:简单与速度 vs. 可靠与功能。 下面我们详细展开对比。 Redis Pub/Sub 的核心特点 它是一个发后…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
深度学习水论文:mamba+图像增强
🧀当前视觉领域对高效长序列建模需求激增,对Mamba图像增强这方向的研究自然也逐渐火热。原因在于其高效长程建模,以及动态计算优势,在图像质量提升和细节恢复方面有难以替代的作用。 🧀因此短时间内,就有不…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
