【Springboot】事件机制发布与订阅的使用实践
文章目录
- 为什么要使用事件监听机制
- 概念和原理
- 使用场景
- 用户注册系统实践案例
- 1. 创建事件类
- 2. 发布事件
- 3. 监听事件
- 3.1 通过注解@EventListener实现监听
- 3.2 通过实现ApplicationListener接口实现监听
- 4. 测试事件机制
- 总结
为什么要使用事件监听机制
在Springboot中,事件机制(Event Mechanism)是一种强大的工具,用于解耦组件之间的通信。通过事件机制,组件可以通过发布和监听事件来进行交互。本文将介绍Springboot的事件监听机制的概念原理、其使用场景,并通过一个实践例子展示其使用过程。
概念和原理
ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现,Springboot内部的事件机制是基于观察者模式(Observer Pattern)。在这种模式下,有两个主要角色:事件发布者(Event Publisher)和事件监听者(Event Listener)。事件发布者发布事件,而事件监听者监听并处理这些事件。
在Springboot中,事件机制主要由以下几个部分组成:
- 事件(Event):事件是继承自
ApplicationEvent的类,用于封装事件相关的信息。 - 事件发布者(Event Publisher):事件发布者通常是Spring应用上下文(ApplicationContext),它提供了发布事件的方法。
- 事件监听者(Event Listener):事件监听者是带有
@EventListener注解的方法或实现ApplicationListener接口的类,用于处理特定类型的事件。
使用场景
Spring Boot的事件机制在以下场景中非常有用:
- 解耦模块之间的通信:不同模块之间可以通过事件进行通信,避免直接依赖,从而提高系统的灵活性和可维护性。
- 实现异步处理:某些操作可以通过事件机制异步处理,提升应用的性能。例如,用户注册后发送欢迎邮件。
- 状态变更通知:当系统状态发生变化时,可以通过事件机制通知相关组件。例如,订单状态变更通知。
用户注册系统实践案例
下面通过一个实践例子来介绍Springboot事件机制的使用过程。我们将创建一个简单的用户注册系统,在用户注册成功后发布一个事件,并由监听器监听该事件并发送欢迎邮件。
1. 创建事件类
首先,创建一个事件类UserRegistrationEvent,继承自ApplicationEvent:
package com.example.demo.events;import org.springframework.context.ApplicationEvent;public class UserRegistrationEvent extends ApplicationEvent {private final String username;public UserRegistrationEvent(Object source, String username) {super(source);this.username = username;}public String getUsername() {return username;}
}
2. 发布事件
在用户注册成功后发布事件:
package com.example.demo.services;import com.example.demo.events.UserRegistrationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Service;@Service
public class UserService {@Autowiredprivate ApplicationEventPublisher eventPublisher;// 或者使用ApplicationContext//@AutoWired//private ApplicationContext applicationContext;public UserService(ApplicationEventPublisher eventPublisher) {this.eventPublisher = eventPublisher;}public void registerUser(String username) {// 处理用户注册逻辑System.out.println("User " + username + " registered successfully.");// 发布事件UserRegistrationEvent event = new UserRegistrationEvent(this, username);eventPublisher.publishEvent(event);// 使用applicationcontext同样// applicationContext.publishEvent(event);}
}
3. 监听事件
3.1 通过注解@EventListener实现监听
创建一个事件监听器类,监听UserRegistrationEvent事件:
package com.example.demo.listeners;import com.example.demo.events.UserRegistrationEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;@Component
public class UserRegistrationListener {@EventListenerpublic void handleUserRegistrationEvent(UserRegistrationEvent event) {System.out.println("Sending welcome email to " + event.getUsername());// 发送欢迎邮件的逻辑}
}
3.2 通过实现ApplicationListener接口实现监听
除了使用@EventListener注解来监听事件外,还可以通过实现ApplicationListener接口来监听事件。这种方式更为传统且显式,适用于更复杂的事件处理逻辑。
package com.example.demo.listeners;import com.example.demo.events.UserRegistrationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;@Component
public class UserRegistrationListenerViaInterface implements ApplicationListener<UserRegistrationEvent> {@Overridepublic void onApplicationEvent(UserRegistrationEvent event) {System.out.println("Handling user registration event via ApplicationListener: " + event.getUsername());// 发送欢迎邮件的逻辑}
}
4. 测试事件机制
最后,创建一个简单的测试类,模拟用户注册:
package com.example.demo;import com.example.demo.services.UserService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;@SpringBootApplication
public class DemoApplication {public static void main(String[] args) {SpringApplication.run(DemoApplication.class, args);}@Beanpublic CommandLineRunner demo(UserService userService) {return args -> {userService.registerUser("JohnDoe");};}
}
运行应用程序后,您将看到控制台输出:
User JohnDoe registered successfully.
Sending welcome email to JohnDoe
总结
通过本文的介绍,我们了解了Spring Boot的事件机制以及其使用场景,并通过一个实践例子展示了如何使用事件机制解耦组件之间的通信。在实际应用中,事件机制可以极大地提高系统的灵活性和可维护性,是一种值得掌握的工具。
相关文章:
【Springboot】事件机制发布与订阅的使用实践
文章目录 为什么要使用事件监听机制概念和原理使用场景用户注册系统实践案例1. 创建事件类2. 发布事件3. 监听事件3.1 通过注解EventListener实现监听3.2 通过实现ApplicationListener接口实现监听 4. 测试事件机制 总结 为什么要使用事件监听机制 在Springboot中,…...
新版网页无插件H.265播放器EasyPlayer.js如何测试demo视频?
H5无插件流媒体播放器EasyPlayer属于一款高效、精炼、稳定且免费的流媒体播放器,可支持多种流媒体协议播放,支持H.264与H.265编码格式,性能稳定、播放流畅;支持WebSocket-FLV、HTTP-FLV,HLS(m3u8࿰…...
PXE、Kickstart和cobbler
一.系统装机 1.1 三种引导方式 启动操作系统 1.硬盘 2.光驱(u盘) 3.网络启动 pxe 1.2 系统安装过程 1.加载boot loader: Boot Loader 是在操作系统内核运行之前运行的一段小程序。通过这段小程序,我们可以初始化硬件设 备、建立内存空间的映射图,从而将系统的软硬…...
【GameFramework扩展应用】6-3、GameFramework框架增加日志保存功能
推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址QQ群:398291828大家好,我是佛系工程师☆恬静的小魔龙☆,不定时更新Unity开发技巧,觉得有用记得一键三连哦。 一、前言 【GameFramework框架】系列教程目录: https://blog.csdn.net/q764424567/article/details/1…...
将独热码应用到神经网络中
引言 接上回,本文继续说如何用TensorFlow将独热编码应用到一个简单的神经网络中,以实现从一段随机文本到另一段随机文本的转换。 步骤一:导入库 import tensorflow as tf import numpy as np import random import string步骤二࿱…...
在CSS中,使用Flexbox布局时,可以通过几个属性来控制容器内的项目之间的间距
display弹性布局,flex:1是占据剩下的空间 关于displa:flex /* 水平和垂直居中,水平和垂直方向上的间距均匀分布 / .container { display: flex; justify-content: space-between; / 左右对齐 / align-items: center; / 上下间距 */ flex-direction: ro…...
关于HDFS 和HBase
Apache HBase 被设计为在 Hadoop 分布式文件系统 (HDFS) 上运行的一个特殊类型的数据库。大白话: 想象一下,你有一个巨大的图书馆,这个图书馆就像 HDFS,它的架子上堆满了各种各样的书籍,每本书都非常厚,而…...
【HarmonyOS】HarmonyOS NEXT学习日记:二、ArkTs语法
【HarmonyOS】HarmonyOS NEXT学习日记:二、ArkTs语法 众所周知TS是JS的超集,而ArkTs则可以理解为是Ts的超集。他们的基础都基于JS,所以学习之前最好就JS基础。我的学习重点也是放在ArkTs和JS的不同点上。 文章主要跟着官方文档学习,跳过了一…...
Web前端-Web开发CSS基础2-选择器
一. 基础 1. 选中所有的<p>标签; 2. 选中所有的<ol>标签; 3. 选中所有的<ul>标签; 4. 选中所有id为happy的标签; 5. 选中所有id为sad的标签; 6. 选中所有id为angry的标签; 7. 选中所有类…...
Mongodb数组字段索引之多键索引
学习mongodb,体会mongodb的每一个使用细节,欢迎阅读威赞的文章。这是威赞发布的第92篇mongodb技术文章,欢迎浏览本专栏威赞发布的其他文章。如果您认为我的文章对您有帮助或者解决您的问题,欢迎在文章下面点个赞,或者关…...
[Spring] Spring Web MVC案例实战
🌸个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 🏵️热门专栏: 🧊 Java基本语法(97平均质量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 🍕 Collection与…...
大模型“重构”教育:解构学习奥秘,推动教育普惠
大模型“重构”千行百业系列选题 生成式人工智能的热潮,为AI领域的发展注入新的活力,而“赋能千行百业”已经成为人们普遍对于人工智能和大模型的全新理解。 人工智能和大模型技术的迅猛发展正在以前所未有的速度深刻改变着各个行业。正如专家所预测&a…...
HCNA VRP基础
交换机可以隔离冲突域,路由器可以隔离广播域,这两种设备在企业网络中应用越来越广泛。随着越来越多的终端接入到网络中,网络设备的负担也越来越重,这时网络设备可以通过专有的VRP系统来提升运行效率。通过路由平台VRP是华为公司数…...
单片机外围设备-EEPROM
eeprom用iic通信。eeprom有几个特点需要关注: 1、可以单字节读写 2、eeprom按页划分存储,不同型号的eeprom的页大小不一致,往eeprom写数据时,如果写到了该页的末尾,会自动从该页的开头继续写,把之前的数据…...
YOLO--置信度(超详细解读)
YOLO(You Only Look Once)算法中的置信度(Confidence)是一个关键概念,用于评估模型对预测框内存在目标对象的信心程度以及预测框对目标对象位置的准确性。 一、置信度的定义 数值范围:置信度是一个介于0和…...
“解锁物流新纪元:深入探索‘沂路畅通‘分布式协作平台“
"解锁物流新纪元:深入探索沂路畅通分布式协作平台" 在21世纪的数字浪潮中,物流行业作为连接生产与消费的关键纽带,其重要性不言而喻。然而,随着市场规模的持续扩大和消费者需求的日益多样化,传统物流模式已…...
昇思25天学习打卡营第六天|应用实践/计算机视觉/Vision Transformer图像分类
心得 运行模型似乎有点靠天意?每次跑模型之前先来个焚香沐浴?总之今天是机器视觉的最后一课了,尽管课程里强调模型跑得慢,可是我的这次运行,居然很快的就看到结果了。 如果一直看我这个系列文章的小伙伴,…...
vxe-table合并行数据
场景: 混批名称相同合并混批名称,在混批名称相同条件下合并相同的混批类型;在混混批类型相同条件下合并相同的混批值;在混批值相同条件下合并相同的单位 实现根据四个不同的key值,当四个key值对应相等时,合…...
LabVIEW异步和同步通信详细分析及比较
1. 基本原理 异步通信: 原理:异步通信(Asynchronous Communication)是一种数据传输方式,其中数据发送和接收操作在独立的时间进行,不需要在特定时刻对齐。发送方在任何时刻可以发送数据,而接收…...
【多模态学习笔记二】MINIGPT-4论文阅读
MINIGPT-4:ENHANCING VISION-LANGUAGE UNDERSTANDING WITH ADVANCED LARGE LANGUAGE MODELS 提出的MiniGPT-4使用一个投影层,将冻结的视觉编码器与冻结的先进的LLM Vicuna对齐。我们的工作首次揭示,将视觉特征与先进的大型语言模型正确对齐可以具有GPT-4所展示的许多先进的多…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
Vite中定义@软链接
在webpack中可以直接通过符号表示src路径,但是vite中默认不可以。 如何实现: vite中提供了resolve.alias:通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...
6.9-QT模拟计算器
源码: 头文件: widget.h #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QMouseEvent>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);…...
