spring boot(2.4.x之前版本)和spring cloud项目中自动装配的监听执行顺序

news2024/10/7 4:36:13

目录

扫描 org.springframework.context.ApplicationListener 指定的类

内置的监听

spring boot 中的监听

spring boot autoconfigure 中的监听

spring boot context 中的监听

将加载的监听进行排序

spring boot 中的监听

spring boot context 中的监听

监听执行

监听加载到 SpringApplicationRunListeners 中

调用 SpringApplicationRunListeners 的 environmentPrepared() 进行监听调用

总结


在前面的文章基础上

https://blog.csdn.net/zlpzlpzyd/article/details/136065211

spring 相关的项目中的代码一直在变,下面以 spring boot 2.3.12.RELEASE 以及对应的 spring cloud Hoxton.SR12 进行说明。

spring boot 在启动时会通过 SpringFactoriesLoader 加载 classpath 下 META-INF/spring.factories 中的对应的类。

扫描 org.springframework.context.ApplicationListener 指定的类

其中监听对应的接口为 ApplicationListener,对应的监听是其实现类实现对应的功能。

内置的监听

spring boot 中的监听

org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.ConfigFileApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.ClasspathLoggingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.liquibase.LiquibaseServiceLocatorApplicationListener

除了 ClearCachesApplicationListener 和 LiquibaseServiceLocatorApplicationListener 都实现了 spring 的接口 Ordered。

spring boot autoconfigure 中的监听

org.springframework.context.ApplicationListener=\
org.springframework.boot.autoconfigure.BackgroundPreinitializer

只有一个 BackgroundPreinitializer,通过注解 @Order 指定了顺序。

spring boot context 中的监听

org.springframework.context.ApplicationListener=\
org.springframework.cloud.bootstrap.BootstrapApplicationListener,\
org.springframework.cloud.bootstrap.LoggingSystemShutdownListener,\
org.springframework.cloud.context.restart.RestartListener

都实现了 spring 的接口 Ordered。

将加载的监听进行排序

在 SpringApplication#getSpringFactoriesInstances() 中通过 AnnotationAwareOrderComparator.sort() 进行处理

其中排序逻辑在父类 OrderComparator 中进行实现。

 

如果当前监听实现了接口 Ordered,则按照对应的编号进行比较,否则直接返回最低优先级,即 Integer.MAX_VALUE。

findOrder() 在子类 AnnotationAwareOrderComparator 中进行重写,用于处理使用注解 @Order 标记的类。

spring boot 中的监听

对应的监听排序如下

CloudFoundryVcapEnvironmentPostProcessor
Integer.MIN_VALUE + 10 - 1

ConfigFileApplicationListener
Integer.MIN_VALUE + 10

AnsiOutputApplicationListener
Integer.MIN_VALUE + 10 + 1

LoggingApplicationListener
Integer.MIN_VALUE + 20

ClasspathLoggingApplicationListener
Integer.MIN_VALUE + 20 + 1

DelegatingApplicationListener
0

ParentContextCloserApplicationListener
Integer.MAX_VALUE - 10

FileEncodingApplicationListener
Integer.MAX_VALUE

ClearCachesApplicationListener
Integer.MAX_VALUE

LiquibaseServiceLocatorApplicationListener
Integer.MAX_VALUE

实际执行结果

spring boot context 中的监听

对应的监听排序如下

BootstrapApplicationListener
Integer.MIN_VALUE + 5

LoggingSystemShutdownListener
Integer.MIN_VALUE + 5 + 1

RestartListener
0

结合 spring boot 启动后的顺序如下

BootstrapApplicationListener
Integer.MIN_VALUE + 5

LoggingSystemShutdownListener
Integer.MIN_VALUE + 5 + 1

CloudFoundryVcapEnvironmentPostProcessor
Integer.MIN_VALUE + 10 - 1

ConfigFileApplicationListener
Integer.MIN_VALUE + 10

AnsiOutputApplicationListener
Integer.MIN_VALUE + 10 + 1

LoggingApplicationListener
Integer.MIN_VALUE + 20

ClasspathLoggingApplicationListener
Integer.MIN_VALUE + 20 + 1

DelegatingApplicationListener
0

RestartListener
0

ParentContextCloserApplicationListener
Integer.MAX_VALUE - 10

FileEncodingApplicationListener
Integer.MAX_VALUE

ClearCachesApplicationListener
Integer.MAX_VALUE

LiquibaseServiceLocatorApplicationListener
Integer.MAX_VALUE

 实际执行结果

可以看到,引入 spring cloud 组件后,默认执行 BootstrapApplicationListener 中的逻辑加载 bootstrap 相关的配置。

监听执行

监听加载到 SpringApplicationRunListeners 中

上面的监听先加载到了 SpringApplicationRunListeners,内部通过一个集合存储SpringApplicationRunListener 的实现类 EventPublishingRunListener 进行存储以进行后续处理。

通过 SpringApplication#getRunListeners() 进行加载

通过反射创建,构造器参数中传入当前类 SpringApplication。

将 SpringApplication 中加载的监听添加到接口 ApplicationEventMulticaster 的实现类。

SimpleApplicationEventMulticaster 的父类 AbstractApplicationEventMulticaster 的内部类 DefaultListenerRetriever 的变量 applicationListeners 中。

调用 SpringApplicationRunListeners 的 environmentPrepared() 进行监听调用

调用 SpringApplicationRunListeners#environmentPrepared() 间接调用 SpringApplicationRunListener 的 environmentPrepared(),对应的实现类为 EventPublishingRunListener。

执行 SpringApplication#prepareEnvironment()

调用 SimpleApplicationEventMulticaster 的 multicastEvent()

调用 SpringApplicationRunListener#environmentPrepared()

调用 SimpleApplicationEventMulticaster#multicastEvent(),参数为事件 ApplicationEnvironmentPreparedEvent。

循环遍历监听,看是否支持对应的事件

由于排序靠前的监听中 ConfigFileApplicationListener 中引入了 ApplicationEnvironmentPreparedEvent,所以优先处理。

调用了 ConfigFileApplicationListener#onApplicationEvent() 后,处理步骤如下

判断当前事件是否为 ApplicationEnvironmentPreparedEvent 的实例,符合条件,执行后续处理。

加载 classpath 中 META-INF/spring.factories 中指定的 EnvironmentPostProcessor 的实现类。

加载当前类为到 EnvironmentPostProcessor  中并进行排序,ConfigFileApplicationListener 实现了接口 EnvironmentPostProcessor。

执行 EnvironmentPostProcessor#postProcessEnvironment() 进行配置文件加载。

总结

综合上述表述,如果引入了 BootstrapApplicationListener 则优先加载,但是在源码中发现如下

正好对应了我们平时写的 spring boot 启动类,可知,在启动时,如果引入了 spring cloud 组件,会先创建一个子容器来加载对应的配置,然后传递到父容器中进行参数传递,完成参数加载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1438079.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apache Paimon 文件操作

本文旨在澄清不同文件操作对文件的影响。 本页面提供具体示例和实用技巧,以有效地管理这些操作。此外,通过对提交(commit)和压实(compact)等操作的深入探讨,我们旨在提供有关文件创建和更新的见…

006集——where语句进行属性筛选——arcgis

在arcgis中, dBASE 文件除了 WHERE 语句以外,不支持 其它 SQL 命令。选择窗口如下: 首先,我们了解下什么是where语句。 WHERE语句是SQL语言中使用频率很高的一种语句。它的作用是从数据库表中选择一些特定的记录行来进行操作。WHE…

第二证券:沪指涨近1%收复2800点,券商等板块拉升,稀土板块爆发

7日早盘,两市股指延续昨日强势,再度拉升。沪指涨近1%克复2800点,深成指、科创50指数大涨约3%;两市半日成交超6000亿元,北向资金净买入超20亿元。 截至午间收盘,沪指涨0.91%报2814.89点,深成指涨…

第1章 认识Flask

学习目标 了解Flask框架,能够说出Flask框架的发展史以及特点 熟悉隔离Python环境的创建方式,能够独立在计算机上创建隔离的Python环境 掌握Flask的安装方式,能够独立在计算机上安装Flask框架 掌握PyCharm配置隔离环境的方式,能…

电脑文件误删除怎么办?8个恢复软件解决电脑磁盘数据可能的误删

您是否刚刚发现您的电脑磁盘数据丢失了?不要绝望!无论分区是否损坏、意外格式化或配置错误,存储在其上的文件都不一定会丢失到数字深渊。 我们已经卷起袖子,深入研究电脑分区恢复软件的广阔领域,为您带来一系列最有效…

如何在 emacs 上开始使用 Tree-Sitter (archlinux)

文章目录 如何在emacs上开始使用Tree-Sitter(archlinux) 如何在emacs上开始使用Tree-Sitter(archlinux) 在archlinux上使用比windows上不知道要方便多少倍! $ sudo pacman -S emacs $ sudo pacman -S tree-sitter这里…

国内首个openEuler师训营圆满结营! 麒麟信安助力培养国产操作系统高质量师资人才

2024年1月22日,全国首个openEuler师训营圆满结营!旨在深化产教融合,加速开源教育走进高校,提高师资队伍openEuler专业能力及实践教学水平。 本次师训营由长沙市大数据产业链、长沙市新一代自主安全计算系统产业链指导&#xff0c…

RxJava Subject

目录 AsyncSubjectBehaviorSubjectPublishSubjectReplaySubjectSerializedSubjectUnicastSubject 在Rxjava中, Subject可以同时表示Observer和Observable, 允许从单个源到多个子观察者multiple child Observers。 除了 onSubscribe(io.reactivex.disposables.Dispos…

云计算运维1

1、企业服务器LNMP环境搭建 集群:多台服务器在一起作同样的事 。分布式 :多台服务器在一起作不同的事 。 环境准备: 1、设置静态ip(NAT模式网关为.2) # cat /etc/sysconfig/network-scripts/ifcfg-ens33 TYPE"E…

【C生万物】C语言分支和循环语句

📚博客主页:爱敲代码的小杨. ✨专栏:《Java SE语法》 | 《数据结构与算法》 | 《C生万物》 ❤️感谢大家点赞👍🏻收藏⭐评论✍🏻,您的三连就是我持续更新的动力❤️ 🙏小杨水平有…

uniapp /微信小程序 使用map组件实现手绘地图方案

获取地图范围 点图拾取坐标-地图开放平台|腾讯位置服务 获取需要手绘地图左下角和右上角GPS坐标 以北京故宫为例&#xff1a; 截取需要手绘地图进行手绘地图制作 ​​​​​​​​​​​​​​ 素材处理 由于地图素材文件比较大&#xff0c;小程序又限制包大小<2M,无…

51单片机基础:定时器

1.定时器介绍 51单片机通常有两个定时器&#xff1a;定时器 0/1&#xff0c;好一点的可能有定时器3。 在介绍定时器之前我们先科普下几个知识&#xff1a; 1&#xff0c;CPU 时序的有关知识 ①振荡周期&#xff1a;为单片机提供定时信号的振荡源的周期&#xff08;晶振周期或…

RAPTOR:树组织检索的递归抽象处理

RAPTOR: RECURSIVE ABSTRACTIVE PROCESSING FOR TREE-ORGANIZED RETRIEVAL Title&#xff1a;树组织检索的递归抽象处理 https://arxiv.org/pdf/2401.18059.pdf 摘要 检索增强语言模型可以更好的融入长尾问题&#xff0c;但是现有的方法只检索短的连续块&#xff0c;限制了整…

深度测评:ONLYOFFICE 桌面编辑器 v8.0新功能

目录 前言 一、PDF表单处理&#xff1a;提升办公效率 二、RTL&#xff08;从右到左&#xff09;支持&#xff1a;满足不同语言习惯 三、Moodle集成&#xff1a;教育行业的新助力 四、本地界面主题&#xff1a;个性化办公体验 五、性能优化与稳定性提升 六、性能与稳定性…

Ubuntu Linux使用PL2302串口和minicom进行开发板调试

调试远程的服务器上面的BMC&#xff0c;服务器上面安装了Ubuntu&#xff0c;想着可以在服务器接个串口到BMC&#xff0c;然后SSH到服务器的Ubuntu&#xff0c;用minicom来查看串口信息。 准备&#xff1a; 服务器Ubuntu安装mimicom 本机可以ssh到Ubuntu 串口工具PL2302 或者CH3…

React+Antd+tree实现树多选功能(选中项受控+支持模糊检索)

1、先上效果 树型控件&#xff0c;选中项形成一棵新的树&#xff0c;若父选中&#xff0c;子自动选中&#xff0c;子取消&#xff0c;父不取消&#xff0c;子选中&#xff0c;所有的父节点自动取消。同时支持模糊检索&#xff0c;会检索出所有包含该内容的关联节点。 2、环境准…

【iOS ARKit】人形遮挡

人形遮挡简介 在 AR系统中&#xff0c;计算机通过对设备摄像头采集的图像进行视觉处理和组织&#xff0c;建立起实景空间&#xff0c;然后将生成的虚拟对象依据几何一致性原理嵌入到实景空间中&#xff0c;形成虚实融合的增强现实环境&#xff0c;再输出到显示系统中呈现给使用…

6.electron之上下文隔离,预加载JS脚本

如果可以实现记得点赞分享&#xff0c;谢谢老铁&#xff5e; Electron是一个使用 JavaScript、HTML 和 CSS 构建桌面应用程序的框架。 Electron 将 Chromium 和 Node.js 嵌入到了一个二进制文件中&#xff0c;因此它允许你仅需一个代码仓库&#xff0c;就可以撰写支持 Windows、…

白嫖10款游戏加速器,一年都不用开会员!

过年期间你们是走亲串戚还是窝家玩游戏、追剧&#xff1f;相信很多小伙伴都不会放过这个难得的假期&#xff0c;肯定是会百忙之中来两把的&#xff0c;那么人一多玩游戏肯定就会拥堵&#xff0c;有延迟。解决延迟最好的办法就是用加速器&#xff0c;当你的网络比别人强时&#…

Rust通用代码生成器莲花发布红莲尝鲜版二十一,前端代码生成物有巨大改进

Rust通用代码生成器莲花发布红莲尝鲜版二十一&#xff0c;前端代码生成物有巨大改进 Rust通用代码生成器莲花已发布红莲尝鲜版二十一&#xff0c;此版本采用了新的前端代码生成引擎&#xff1a;时空之门前端代码生成器6.2.0。此引擎支持Nodejs 21,Nodejs 18和Nodejs 14。消除了…