当前位置: 首页 > 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连接数据库之后看一下 一共四层结构 库 》表》字段》数据 这个层级关系…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

线程与协程

1. 线程与协程 1.1. “函数调用级别”的切换、上下文切换 1. 函数调用级别的切换 “函数调用级别的切换”是指&#xff1a;像函数调用/返回一样轻量地完成任务切换。 举例说明&#xff1a; 当你在程序中写一个函数调用&#xff1a; funcA() 然后 funcA 执行完后返回&…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

脑机新手指南(七):OpenBCI_GUI:从环境搭建到数据可视化(上)

一、OpenBCI_GUI 项目概述 &#xff08;一&#xff09;项目背景与目标 OpenBCI 是一个开源的脑电信号采集硬件平台&#xff0c;其配套的 OpenBCI_GUI 则是专为该硬件设计的图形化界面工具。对于研究人员、开发者和学生而言&#xff0c;首次接触 OpenBCI 设备时&#xff0c;往…...