(五)springboot实战——springboot自定义事件的发布和订阅
前言
本节内容我们主要介绍一下springboot自定义事件的发布与订阅功能,一些特定应用场景下使用自定义事件发布功能,能大大降低我们代码的耦合性,使得我们应用程序的扩展更加方便。就本身而言,springboot的事件机制是通过观察者设计模式实现。通过ApplicationListener事件监听器实现事件的发布与订阅。我们以登录场景为例,假如用户登录之后,需要发送登录通知、发送邮件通知、发送签到通知,如果按照常规做法,我们可以顺序执行以上操作,但是使用springboot的事件机制,我们可以发布一个登录的事件消息,然后各自去消费登录这个事件消息,这样达到业务解耦的效果。
正文
①创建一个事件发布器,用于发送自定义的消息事件
- 实现代码:通过实现ApplicationEventPublisherAware 接口
package com.yundi.isbc.event.publish;import org.springframework.context.ApplicationEvent; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.stereotype.Component;@Component public class MyApplicationEventPublisherAware implements ApplicationEventPublisherAware {private ApplicationEventPublisher applicationEventPublisher;@Overridepublic void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {this.applicationEventPublisher = applicationEventPublisher;}/*** 消息事件发布* @param applicationEvent*/public void publishEvent(ApplicationEvent applicationEvent) {applicationEventPublisher.publishEvent(applicationEvent);} }
②创建一个登录的自定义消息事件
- 实现代码:通过继承ApplicationEvent事件实现自定义消息事件
package com.yundi.isbc.event.publish;import com.yundi.isbc.entity.User; import org.springframework.context.ApplicationEvent;public class LoginApplicationEvent extends ApplicationEvent {public LoginApplicationEvent(User user) {super(user);} }
③创建一个用户实体类,用于数据的传输
- 实现代码
package com.yundi.isbc.entity;import lombok.Data; import lombok.experimental.Accessors;@Accessors(chain = true) @Data public class User {/*** 用户名*/private String username;/*** 密码*/private String password; }
④创建一个控制器LoginController,用于登录业务处理,并发布登录事件
- 实现代码
package com.yundi.isbc.controller;import com.yundi.isbc.entity.User; import com.yundi.isbc.event.publish.LoginApplicationEvent; import com.yundi.isbc.event.publish.MyApplicationEventPublisherAware; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;@RestController @RequestMapping("/index") public class LoginController {@Autowiredprivate MyApplicationEventPublisherAware myApplicationEventPublisherAware;@GetMapping("login")public String login() {//发布登录事件myApplicationEventPublisherAware.publishEvent(new LoginApplicationEvent(new User().setUsername("xiaoming").setPassword("123456")));//todo 主流程业务处理return "ok";}}
- 代码说明
⑤ 通过实现ApplicationListener接口,实现登录通知消息的消费,并做相关的业务处理
- 实现代码
package com.yundi.isbc.event.describe;import com.yundi.isbc.entity.User; import com.yundi.isbc.event.publish.LoginApplicationEvent; import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Service;@Service public class LoginNotifyListen implements ApplicationListener<LoginApplicationEvent> {public void accumulateLogin(User user) {System.out.println("=======登录业务======" + user);}@Overridepublic void onApplicationEvent(LoginApplicationEvent event) {System.out.println("===============收到登录通知事件===================");User user = (User) event.getSource();accumulateLogin(user);} }
⑥通过@EventListener方式订阅消息,实现邮件业务处理,该种方式更加灵活,不用实现ApplicationListener接口
- 实现代码
package com.yundi.isbc.event.describe;import com.yundi.isbc.entity.User; import com.yundi.isbc.event.publish.LoginApplicationEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service;@Service public class MailNotifyListen {public void mailNotify(User user) {System.out.println("=======邮件业务======" + user);}@EventListenerpublic void onLoginEvent(LoginApplicationEvent loginApplicationEvent) {System.out.println("===============收到登录通知事件===================");User user = (User) loginApplicationEvent.getSource();mailNotify(user);} }
⑦通过@EventListener方式订阅消息,实现签到业务处理
-实现代码
package com.yundi.isbc.event.describe;import com.yundi.isbc.entity.User; import com.yundi.isbc.event.publish.LoginApplicationEvent; import org.springframework.context.event.EventListener; import org.springframework.stereotype.Service;@Service public class SignNotifyListen {public void signNotify(User user) {System.out.println("=======签到业务======" + user);}@EventListenerpublic void onLoginEvent(LoginApplicationEvent loginApplicationEvent) {System.out.println("===============收到登录通知事件===================");User user = (User) loginApplicationEvent.getSource();signNotify(user);} }
⑧验证结果,访问登录接口,查看控制台,所有订阅事件的业务都能正常订阅消费
结语
关于springboot自定义事件的发布和订阅的内容到这里就结束了,我们下期见。。。。。。
相关文章:

(五)springboot实战——springboot自定义事件的发布和订阅
前言 本节内容我们主要介绍一下springboot自定义事件的发布与订阅功能,一些特定应用场景下使用自定义事件发布功能,能大大降低我们代码的耦合性,使得我们应用程序的扩展更加方便。就本身而言,springboot的事件机制是通过观察者设…...

AVFoudation - 音频测量
文章目录 关于 metering使用关于 metering AVAudioPlayer 和 AVAudioRecorder 都有 metering 相关方法,用于音频测量 /* metering */@property(getter=isMeteringEnabled) BOOL meteringEnabled; /* turns level metering on or off. default is off. */ - (void)updateMet…...

学习记录——TransNormerLLM
Scaling TransNormer to 175 Billion Parametes 线性注意力的Transformer大模型 2023 Transformer 存在局限。首要的一点,它们有着对于序列长度的二次时间复杂度,这会限制它们的可扩展性并拖累训练和推理阶段的计算资源和时间效率。 TransNormerLLM 是首…...

【Qt】利用Tool Button控件创建下拉菜单按钮
功能描述 利用qt进行界面设计和开发,创建下拉按钮。 详细实现 1、在qt侧工具栏利用设计打开.ui文件 2、创建按钮 创建一个Tool Button按钮,并在属性窗口中的QToolButton栏中选中MenuButtonPopup属性。 3、创建action 在Action编辑器创建对应的ac…...

1.2 eureka注册中心,完成服务注册
目录 环境搭建 搭建eureka服务 导入eureka服务端依赖 编写启动类,添加EnableEurekaServer注解 编写eureka配置文件 启动服务,访问eureka Euraka服务注册 创建了两个子模块 在模块里导入rureka客户端依赖 编写eureka配置文件 添加Services 环境搭建 创建父…...

【100天精通python】Day20:文件及目录操作_os模块和os.psth模块,文件权限修改
目录 专栏导读 1 文件的目录操作 os模块的一些操作目录函数编辑 os.path 模块的操作目录函数 2 相对路径和绝对路径 3 路径拼接 4 判断目录是否存在 5 创建目录、删除目录、遍历目录 专栏导读 专栏订阅地址:https://blog.csdn.net/qq_35831906/category_12…...

回归预测 | MATLAB实现PSO-GPR粒子群优化高斯过程回归多输入单输出回归预测
回归预测 | MATLAB实现PSO-GPR粒子群优化高斯过程回归多输入单输出回归预测 目录 回归预测 | MATLAB实现PSO-GPR粒子群优化高斯过程回归多输入单输出回归预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab基于PSO-GPR基于粒子群算法优化高斯过程回归的数据回归预…...

python_PyQt5开发验证K线视觉想法工具V1.1 _增加标记类型_线段
目录 运行情况: 代码: 承接 【python_PyQt5开发验证K线视觉想法工具V1.0】 博文 https://blog.csdn.net/m0_37967652/article/details/131966298 运行情况: 添加线段数据在K线图中用线段绘制出来 代码: 1 线段标记的数据格式…...

中文多模态医学大模型智能分析X光片,实现影像诊断,完成医生问诊多轮对话
项目设计集合(人工智能方向):助力新人快速实战掌握技能、自主完成项目设计升级,提升自身的硬实力(不仅限NLP、知识图谱、计算机视觉等领域):汇总有意义的项目设计集合,助力新人快速实…...

企业服务器数据库被360后缀勒索病毒攻击后采取的措施
近期,360后缀勒索病毒的攻击事件频发,造成很多企业的服务器数据库遭受严重损失。360后缀勒索病毒是Beijingcrypt勒索家族中的一种病毒,该病毒的加密形式较为复杂,目前网络上没有解密工具,只有通过专业的技术人员对其进…...

FFmpeg-两个文件mix重采样以那个为主
ffmpeg -i 2ch-44.1k.wav -i 2ch-16k.wav -filter_complex " \ [0:a][1:a]amixinputs2[aout]" \ -map [aout] -f null -ffmpeg -i 2ch-44.1k.wav -i 2ch-16k.wav -filter_complex " \ [0:a][1:a]amixinputs2[aout]" \ -map [aout] -f null -对比发现&#…...

【WebGL】初探WebGL,我了解到这些
WebGL(Web图形库)是一种强大的技术,允许您在Web浏览器中直接创建交互式的3D图形和动画。它利用现代图形硬件的能力来呈现令人惊叹的视觉效果,使其成为Web开发人员和计算机图形爱好者必备的技能。 WebGL基础知识 WebGL基于OpenGL …...

fwft fifo和standard fifo
fifo共有两种,分别是standard fifo和fwft fifo,其中,前者的latency=1,即rd_en信号有效且fifo非空时,数据会在下一个周期出现在fifo的读数据端口。而后者,即fwft fifo的latency=0,也就是说,rd_en信号有效的当拍,数据就会出现在读端口上。这里,fwft是First-word-Fall-T…...

pdf阅读器哪个好用?这个阅读器别错过
pdf阅读器哪个好用?PDF是一种流行的文件格式,可以保留文档的原始格式、布局和字体。与其他文档格式相比,PDF在不同设备和操作系统上的显示效果更为一致,确保文档内容的准确性和可读性。在阅读一些PDF文件的时候,使用一…...

【LeetCode】下降路径最小和
下降路径最小和 题目描述算法分析编程代码 链接: 下降路径最小和 题目描述 算法分析 编程代码 class Solution { public:int minFallingPathSum(vector<vector<int>>& matrix) {int n matrix.size();vector<vector<int>> dp(n1,vector(n2,INT_M…...

从0到1开发go-tcp框架【2-实现Message模块、解决TCP粘包问题、实现多路由机制】
从0到1开发go-tcp框架【2-实现Message模块、解决TCP粘包问题、实现多路由机制】 1 实现\封装Message模块 zinx/ziface/imessage.go package zifacetype IMessage interface {GetMsdId() uint32GetMsgLen() uint32GetMsgData() []byteSetMsgId(uint32)SetData([]byte)SetData…...

Boost开发指南-3.6weak_ptr
weak_ptr weak_ptr是为配合shared_ptr而引入的一种智能指针,它更像是shared_ptr的一个助手而不是智能指针,因为它不具有普通指针的行为,没有重载 operator*和->。它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使…...

Swift 周报 第三十三期
文章目录 前言新闻和社区App 内购买项目和订阅即将实行价格与税率调整为家庭提供安全的 App 体验 提案正在审查的提案 Swift论坛推荐博文话题讨论关于我们 前言 本期是 Swift 编辑组自主整理周报的第二十四期,每个模块已初步成型。各位读者如果有好的提议ÿ…...

网络空间安全及计算机领域常见英语单词及短语——网络安全(一)
目录 网络空间安全常见英语单词没事儿读着玩儿相关知识扫盲 CSDN的小伙伴们,我快回来咯!网络空间安全常见英语单词 Cybersecurity 网络安全Network security 网络安全Information security 信息安全Data protection 数据保护Threat analysis 威胁分析Ri…...

Go基准测试Benchmark
Go语言自带了一个强大的测试框架,其中包括基准测试(Benchmark)功能,基准测试用于测量和评估一段代码的性能。 我们可以通过在Go的测试文件中编写特殊格式的函数来创建基准测试。测试文件的命名遵守原函数名称_test.go 的格式。 基…...

docker容器的基本操作
一、查看Docker的版本信息 [roothuyang1 ~]# docker version 二、查看docker的详细信息 [roothuyang1 ~]# docker info 三、Docker镜像操作 Docker创建容器前需要本地存在对应的镜像,如果本地加载不到相关镜像,Docker默认就会尝试从镜像仓库https://hu…...

MySQL绿色安装和配置
1、 从地址http://dev.mysql.com/downloads/mysql/中选择windows的版本下载。 2、 mysql各个版本的简介 (1) MySQL Community Server 社区版本,开源免费,但不提供官方技术支持。 (2) MySQL Enterprise Ed…...

《cuda c编程权威指南》03 - cuda小功能汇总
1. 计时 1.1 linux #include <sys/time.h>double cpuSecond() {struct timeval tp;gettimeofday(&tp, NULL);return ((double)tp.tv_sec (double)tp.tv_usec*1e-6); }// 调用 double start cpuSecond(); kernel_name << <grid, block >> > (ar…...

Java:Java程序通过执行系统命令调用Python脚本
本文实现功能:Java程序调用Python脚本 Python脚本 import sysdef add(x, y):return x yif __name__ "__main__":print(add(int(sys.argv[1]), int(sys.argv[2])))直接执行 $ python math.py 1 2 3Java程序调用Python脚本 package io.github.mouday.…...

this is incompatible with sql_mode=only_full_group_by
查看配置 select global.sql_mode 在sql命令行中输入select sql_mode 能够看到sql_mode配置,如果有ONLY_FULL_GROUP_BY,则需要修改 在mysql5.7.5后,ONLY_FULL_GROUP_BY是默认选项,所以就会导致group by的问题 set sql_mode‘复制去掉ONLY_F…...

GCC编译选项
当使用GCC编译器时,可以根据不同的需求选择适当的编译选项来控制编译过程和生成的代码的行为。以下是一些常见的GCC编译选项的归纳: 优化选项: -O0: 不进行优化,保留原始的C代码结构。-O1: 启用基本优化级别,进行简单…...

信息安全战线左移!智能网联汽车安全亟需“治未病”
当汽车由典型的工业机械产品逐步发展成为全新的智能移动终端,汽车的安全边界发生了根本性改变,信息安全风险和挑战不断增加。 面对复杂的异构网络、异构系统及车规级特异性要求,智能智能网联汽车信息安全到底要如何防护,已经成为…...

服务器介绍
本文章转载与b战up主谈三国圈,仅用于学习讨论,如有侵权,请联系博主 机架型服务器 堆出同时服务百万人次机组 刀型服务器 服务器炸了 比如用户访问量暴增 超过机组的峰值处理能力,进而导致卡顿或炸服, 适合企业的塔式…...

Java_25_方法引用
方法引用 方法引用: 方法引用是为了进一步简化Lambda表达式的写法。 方法引用的格式:类型或者对象::引用的方法。 关键语法是:“::” 小结:方法引用可以进一步简化Lambda表达式的写法。关键语法是:“::”范例代码&…...

QT基于TCP协议实现数据传输以及波形绘制——安卓APP及Windows程序双版本
文章代码有非常非常之详细的解析!!!诸位可放心食用 这个玩意我做了两个,一个是安卓app,一个是Windows程序。代码并非全部都是由我从无到有实现,只是实现了我想要的功能。多亏了巨人的肩膀,开源…...