当前位置: 首页 > news >正文

spring-boot自定义ApplicationListener及源码分析

ApplicationListener是spring boot应用启动时的事件监听器。监听的事件有(包括但不限于):

(1)接下来,我们先通过一个例子实现自定义ApplicationListener:

监听器需要实现ApplicationListener<T>,参数类型为ApplicationEvent,表示监听所有事件,当然也可以将参数类型设置为单独的事件,下面这个只会接收ApplicationEnvironmentPreparedEvent事件:

(2)定义了监听器后,还需要配置一下,让spring boot启动时加载它,即配置"context.listener.classes"

(3)启动后可以看到,监听器监听了如下事件:

(4)源码分析,我们来看看自定义的监听器是怎么工作的:

ApplicationListener是采用观察者模式实现的,我们的启动时入口是执行SpringApplication.run方法

如下两处代码,分别是获取SpringApplicationRunListeners(这个是各个事件的发布者)和进行环境的准备,

在环境准备好后发布ApplicationEnvironmentPreparedEvent事件

虽然这里listeners是容器类,但默认只有一个EventPublishingRunListener,我们看一下它是怎么发布事件的,如下代码很明显,进行了一个事件的广播,但还没看到广播给谁,继续往下

这里可以看到getApplicationListeners(event, type),就是根据事件类型获取需要广播的ApplicationListener

在调试状态下,我们看一下getApplicationListeners(event, type)有哪些

发现只有6个ApplicationListener响应了ApplicationEnvironmentPreparedEvent事件,而且没有我们自定义的ApplicationListener,怎么回事呢?

实际上,我们的ApplicationListener是通过代理类执行的,即上面的DelegatingApplicationListener,我们可以看一下它怎么执行的:

上面代码可以看到代理类也监听了所有的事件,然后在ApplicationEnvironmentPreparedEvent事件时才初次响应,并且通过getListeners获取所有代理的ApplicationListeners,然后它自己实现了一个事件广播器,然后把获取的ApplicationListeners通过到addApplicationListener加入到广播器中,最后进行事件的广播转发。我们重点看一下getListeners,看是如何获取到我们自定义的ApplicationListeners的:

我们可以看到,是通过我们配置的context.listener.classes获得类名,然后通过反射实例化返回。

这样整个监听器的过程就完整了。我们注意到代理类是从ApplicationEnvironmentPreparedEvent开始响应的,所以之前的事件我们自定义的ApplicationListener是无法监听的。实际上前面只有一个ApplicationStartingEvent,此时应用才刚启动,也没啥好监听的。如果需要监听所有的事件可以在自己在spring.factories配置:

在resources下新建META-INF\spring.factoies,然后和spring的监听器配置一样配置自己定义的监听器,就可以啦

相关文章:

spring-boot自定义ApplicationListener及源码分析

ApplicationListener是spring boot应用启动时的事件监听器。监听的事件有&#xff08;包括但不限于&#xff09;&#xff1a; &#xff08;1&#xff09;接下来&#xff0c;我们先通过一个例子实现自定义ApplicationListener&#xff1a; 监听器需要实现ApplicationListener<…...

C语言:深入理解指针

一.内存和地址 我们知道计算机上CPU&#xff08;中央处理器&#xff09;在处理数据的时候&#xff0c;需要的数据是在内存中读取的&#xff0c;处理后的数据也会放回内存中&#xff0c;那我们买电脑的时候&#xff0c;电脑上内存是 8GB/16GB/32GB 等&#xff0c;那这些内存空间…...

【WPF实现RichTextBox添加文本、自动滚动】

前言 使用WPF 中的RichTextBox控件实现添加文本后自动滚动末尾。因为RichTextBox无法直接绑定数据&#xff0c;所以通过引用System.Windows.Interactivity实现&#xff08;System.Windows.Interactivity.WPF&#xff09; 代码 MainWindow.xaml <Window x:Class"WPF…...

量化交易系统开发-实时行情自动化交易-8.4.MT4/MT5平台

19年创业做过一年的量化交易但没有成功&#xff0c;作为交易系统的开发人员积累了一些经验&#xff0c;最近想重新研究交易系统&#xff0c;一边整理一边写出来一些思考供大家参考&#xff0c;也希望跟做量化的朋友有更多的交流和合作。 接下来会对于MT4/MT5平台介绍。 MetaT…...

【HarmonyOS】@Observed和@ObjectLink嵌套对象属性更改UI不刷新问题

【HarmonyOS】Observed和ObjectLink嵌套对象属性更改UI不刷新问题 一、问题背景 使用了Observed和ObjectLink&#xff0c;修改嵌套对象的属性&#xff0c;UI还是不刷新&#xff0c;常见的问题有以下三种形式&#xff1a; 1.多级嵌套&#xff0c;嵌套对象的类并没有添加Observ…...

什么是默克尔树(Merkle Tree)?如何计算默克尔根?

默克尔树的概念 默克尔树(Merkle Tree)是一种特殊的二叉树&#xff0c;它的每个节点都存储了一个数据块的哈希值。哈希值是一种可以将任意长度的数据转换为固定长度的字符串的算法&#xff0c;它具有唯一性和不可逆性的特点&#xff0c;即不同的数据块会产生不同的哈希值&…...

眼部按摩仪WT2605音频蓝牙语音芯片方案 单芯片实现语音提示及控制/手机无线音频传输功能

随着科技的快速发展&#xff0c;人们的生活方式也在不断改变&#xff0c;智能化、便捷化的产品逐渐成为市场的主流。眼部按摩仪作为一种结合了现代科技与健康生活理念的产品&#xff0c;受到了广大消费者的青睐。而在众多眼部按摩仪中&#xff0c;采用WT2605音频蓝牙芯片的方案…...

python打包深度学习虚拟环境

今天师兄让我把环境打包发给他&#xff0c;我才知道可以直接打包深度学习虚拟环境&#xff0c;这样另一个人就不用辛辛苦苦的去装环境了&#xff0c;我们都知道有些论文他需要的环境很难装上。比如装Apex&#xff0c;装 DCN&#xff0c;mmcv-full 我现在把3090机子上的ppft虚拟…...

springboot358智慧社区居家养老健康管理系统(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 智慧社区居家养老健康管理系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&…...

复杂网络(二)

一、网络的基本静态几何特征 1.1 度分布 节点的度&#xff1a;在网络中&#xff0c;节点的邻边数称为该节点的度 对于网络中所有节点的度求平均&#xff0c;可得到网络的平均度 度分布&#xff1a;大多数实际网络中的节点的度满足一定的概率分布。定义P(k)为网络中度为k的节…...

Kubernetes 01

MESOS&#xff1a;APACHE 分布式资源管理框架 2019-5 Twitter退出&#xff0c;转向使用Kubernetes Docker Swarm 与Docker绑定&#xff0c;只对Docker的资源管理框架&#xff0c;阿里云默认Kubernetes Kubernetes&#xff1a;Google 10年的容器化基础框架&#xff0c;borg…...

node修改文件名称

node修改名称 var fs require(fs); const events require(events); var path require(path);init(); function init() {//要遍历的文件夹所在的路径const dirPath path.resolve(__dirname, "data");//遍历目录fileDisplay(dirPath); }/*** 文件遍历* param dirP…...

ArcGIS 软件中路网数据的制作

内容导读 路网数据是进行网络分析的基础&#xff0c;它是建立网络数据集的数据来源。 本文我们以OSM路网数据为例&#xff0c;详细介绍OSM路网数据从下载&#xff0c;到数据处理&#xff0c;添加属性&#xff0c;完成符合网络分析的网络数据集的全部过程。 01 数据获取 比较…...

transformers microsoft--table-transformer 表格识别

一、安装包 pip install transformers pip install torch pip install SentencePiecepip install timm pip install accelerate pip install pytesseract pillow pandas pip install tesseract 下载模型&#xff1a; https://huggingface.co/microsoft/table-transformer-s…...

【Spark源码分析】规则框架-草稿

规则批&#xff1a;规则集合序列&#xff0c;由名称、执行策略、规则列表组成。一个规则批里使用一个执行规则。 执行策略 FixedPointOnce 规则&#xff1a; #mermaid-svg-1cvqR4xkYpMuAs77 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px…...

迪米特原则的理解和实践

迪米特原则&#xff08;Law of Demeter&#xff0c;简称LoD&#xff09;&#xff0c;也被称为最少知识原则&#xff08;Least Knowledge Principle&#xff0c;LKP&#xff09;&#xff0c;是面向对象设计中的一个重要原则。其核心思想是&#xff1a;一个对象应该对其他对象有最…...

jQuery零基础入门速通(中)

大家好&#xff0c;我是小黄。 在上一篇文章中&#xff0c;我们初步了解了jQuery的基本概念、环境搭建、选择器、基本的DOM操作以及事件处理。接下来&#xff0c;我们将继续深入探讨jQuery的DOM操作和事件处理&#xff0c;以及一些实用的技巧和高级用法。 五、高级DOM操作 5…...

【设计模式系列】中介者模式(十八)

一、什么是中介者模式 中介者模式&#xff08;Mediator Pattern&#xff09;是一种行为型设计模式&#xff0c;其核心思想是通过一个中介者对象来封装一系列对象之间的交互&#xff0c;使这些对象不需要相互显式引用。中介者模式提供了一个中介层&#xff0c;用以协调各个对象…...

PDF版地形图矢量出现的问题

项目描述&#xff1a;已建风电场道路测绘项目&#xff0c;收集到的数据为PDF版本的地形图&#xff0c;图上标注了项目竣工时期的现状&#xff0c;之后项目对施工区域进行了复垦恢复地貌&#xff0c;现阶段需要准确的知道实际复垦修复之后的道路及其它临时用地的面积 解决方法&…...

小迪安全第四十二天笔记 简单的mysql注入 mysql的基础知识 用户管理数据库模式 mysql 写入与读取 跨库查询

前言 之前的安全开发我们学习了 php联动数据库的模式 &#xff0c;这个模式是现在常用的模式 这一节来学习 如何 进行数据库的注入和数据库相关知识 1、了解数据库的结构 我们使用 navicate连接数据库之后看一下 一共四层结构 库 》表》字段》数据 这个层级关系…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

css3笔记 (1) 自用

outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size&#xff1a;0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格&#xff…...

Java数值运算常见陷阱与规避方法

整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

【 java 虚拟机知识 第一篇 】

目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...

【LeetCode】3309. 连接二进制表示可形成的最大数值(递归|回溯|位运算)

LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 题目描述解题思路Java代码 题目描述 题目链接&#xff1a;LeetCode 3309. 连接二进制表示可形成的最大数值&#xff08;中等&#xff09; 给你一个长度为 3 的整数数组 nums。 现以某种顺序 连接…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案

在移动互联网营销竞争白热化的当下&#xff0c;推客小程序系统凭借其裂变传播、精准营销等特性&#xff0c;成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径&#xff0c;助力开发者打造具有市场竞争力的营销工具。​ 一、系统核心功能架构&…...

人工智能 - 在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型

在Dify、Coze、n8n、FastGPT和RAGFlow之间做出技术选型。这些平台各有侧重&#xff0c;适用场景差异显著。下面我将从核心功能定位、典型应用场景、真实体验痛点、选型决策关键点进行拆解&#xff0c;并提供具体场景下的推荐方案。 一、核心功能定位速览 平台核心定位技术栈亮…...

TCP/IP 网络编程 | 服务端 客户端的封装

设计模式 文章目录 设计模式一、socket.h 接口&#xff08;interface&#xff09;二、socket.cpp 实现&#xff08;implementation&#xff09;三、server.cpp 使用封装&#xff08;main 函数&#xff09;四、client.cpp 使用封装&#xff08;main 函数&#xff09;五、退出方法…...