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

目录

扫描 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 - 1ConfigFileApplicationListener
Integer.MIN_VALUE + 10AnsiOutputApplicationListener
Integer.MIN_VALUE + 10 + 1LoggingApplicationListener
Integer.MIN_VALUE + 20ClasspathLoggingApplicationListener
Integer.MIN_VALUE + 20 + 1DelegatingApplicationListener
0ParentContextCloserApplicationListener
Integer.MAX_VALUE - 10FileEncodingApplicationListener
Integer.MAX_VALUEClearCachesApplicationListener
Integer.MAX_VALUELiquibaseServiceLocatorApplicationListener
Integer.MAX_VALUE

实际执行结果

spring boot context 中的监听

对应的监听排序如下

BootstrapApplicationListener
Integer.MIN_VALUE + 5LoggingSystemShutdownListener
Integer.MIN_VALUE + 5 + 1RestartListener
0

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

BootstrapApplicationListener
Integer.MIN_VALUE + 5LoggingSystemShutdownListener
Integer.MIN_VALUE + 5 + 1CloudFoundryVcapEnvironmentPostProcessor
Integer.MIN_VALUE + 10 - 1ConfigFileApplicationListener
Integer.MIN_VALUE + 10AnsiOutputApplicationListener
Integer.MIN_VALUE + 10 + 1LoggingApplicationListener
Integer.MIN_VALUE + 20ClasspathLoggingApplicationListener
Integer.MIN_VALUE + 20 + 1DelegatingApplicationListener
0RestartListener
0ParentContextCloserApplicationListener
Integer.MAX_VALUE - 10FileEncodingApplicationListener
Integer.MAX_VALUEClearCachesApplicationListener
Integer.MAX_VALUELiquibaseServiceLocatorApplicationListener
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://xiahunao.cn/news/2777917.html

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

相关文章

“智能检测,精准把控。温湿度检测系统,为您的生活带来全方位的健康保障。”#非标协议项目【下】(分文件编程)

“智能检测,精准把控。温湿度检测系统,为您的生活带来全方位的健康保障。”#非标协议项目【下】(分文件编程) 前言预备知识1温湿度检测系统需求2.分文件编程核心思路3.分文件编程操作4利用分文件操作建立uart.c、lcd1602.c、dht11…

《乱弹篇(十二)聊春晚》

龙年大初一,老龄笔者发表《乱弹篇(十二)》。“十二”的标志,乃好事成双“二”。喜庆有余,自不待言! 除夕夜我没有看春晚,是在继续追剧,即以明朝宫廷内斗为背景的电视连续剧《后宫》…

2024年应该关注的十大人工智能创新

人工智能(AI)不再只是一个流行词,它已成为我们日常生活的重要组成部分。人工智能在去年深入地融入我们社会的各个方面,改变我们的生活方式、工作方式以及与技术互动的方式。 今年是大年初一,我们将探讨2024年可能出现…

Python实战:用Python程序实现春晚刘谦魔术

刘谦春晚魔术是一个让人叹为观止的魔术表演,其中涉及到了数学、编程和创意的结合。看了春晚魔术的朋友们,是不是好奇春晚刘谦的魔术是怎么变的。 在这篇文章中,我们将通过 Python 程序实现春晚刘谦魔术,让读者对这个魔术有更深入…

Talk|香港科技大学苟耘豪:MoCLE - 指令聚类MoE+通用专家解决多模态大模型任务冲突

本期为TechBeat人工智能社区第571期线上Talk。 北京时间2月8日(周四)20:00,香港科技大学博士生—苟耘豪的Talk已准时在TechBeat人工智能社区开播! 他与大家分享的主题是: “MoCLE - 指令聚类MoE通用专家解决多模态大模型任务冲突”,系统地介绍…

SAP-PS-02-003跨系统/Client请求传输和请求副本的创建

前言 某公司SAP服务器架构如下(举例),一般进行SAP项目实施基本会遵循以下的系统和Client准则,那在不同系统和Client要如何进行请求传输呢 服务器 Client 作用 要求 DEV 100 业务顾问进行系统配置 所有配置均在该Client进行…

面向工业 X.0 的工业网络简述

此图片来源于网络 1、背景 工业4.0是在21世纪初提出的,特别是在2013年,德国政府正式推出了“工业4.0”战略,旨在通过利用物联网(IoT)等先进技术提高工业的竞争力。因此,我们可以认为工业4.0的实现时间大致…

【C++跬步积累】—— 构造函数+析构函数

🌏博客主页:PH_modest的博客主页 🚩当前专栏:C跬步积累 💌其他专栏: 🔴 每日一题 🟡 每日反刍 🟢 C语言跬步积累 🌈座右铭:广积粮,缓称…

第9讲 详解第 2 套真题

第9讲 详解第 2 套真题 基本编程题【15 分】简单应用题【25 分】综合应用题【20 分】问题 1【10 分】:问题 2【10 分】:各位小伙伴想要博客相关资料的话关注公众号:chuanyeTry即可领取相关资料! 基本编程题【15 分】 考生文件夹下存在一个文件 PY101.py,请写代码替换横线,不…

Acwing---837. 连通块中点的数量

连通块中点的数量 1.题目2.基本思想3.代码实现 1.题目 给定一个包含 n n n个点(编号为 1 ∼ n 1∼n 1∼n)的无向图,初始时图中没有边。 现在要进行 m m m 个操作,操作共有三种: C a b,在点 a 和点 b …

python从入门到精通(十):python常见标准库的使用

python数据分析和可视化基础 (一)Python 中处理日期和时间的模块time导入time模块time获取当前时间戳localtime获取当前时间struct_timeasctime获取格式化的时间ctime获取格式化的时间gmtime获取格式化的时间计时器功能strftime格式化日期strptime格式化…

python巧用定理判断素数

目录 判断一个数n是否是素数 求一个数的素因数个数 求大于等于指定数的最小素数 在数论中有三个非常重要的关于素数的定理 1、任何数都可以表示成若干个素数的乘积 2、任意数的素因子一个大于根号n的自然数,另一个与其对应的因子则必小于根号n。 3、除了2和3以…

fast.ai 机器学习笔记(二)

机器学习 1:第 5 课 原文:medium.com/hiromi_suenaga/machine-learning-1-lesson-5-df45f0c99618 译者:飞龙 协议:CC BY-NC-SA 4.0 来自机器学习课程的个人笔记。随着我继续复习课程以“真正”理解它,这些笔记将继续更…

企业飞书应用机器人,使用python自动发送文字内容到群消息

文章目录 创建企业应用与开通机器人飞书发送信息的工具函数 创建企业应用与开通机器人 需要先创建应用,然后进入应用后,点击添加应用能力创建机器人: 参考官方文档,获取两个参数:app_id与app_secret 官方说明文档&…

低代码市场的未来展望:趋势、机遇与挑战

根据 Zoho 的一项新研究,低代码市场正处于成为主流的风口浪尖。该报告对全球 800 多名 IT 和业务领导者进行了调查,确定了推动其采用的几个因素。其中最重要的是提高应用程序的开发速度。 这一发现对企业领导者来说应该不足为奇。 客户、合作伙伴和员工…

6 scala-面向对象编程基础

Scala 跟 Java 一样,是一门面向对象编程的语言,有类和对象的概念。 1 类与对象 与 Java 一样,Scala 也是通过关键字 class 来定义类,使用关键字 new 创建对象。 要运行我们编写的代码,同样像 Java 一样,…

4核8g服务器能访问多少人?2024年测评

腾讯云轻量4核8G12M轻量应用服务器支持多少人同时在线?通用型-4核8G-180G-2000G,2000GB月流量,系统盘为180GB SSD盘,12M公网带宽,下载速度峰值为1536KB/s,即1.5M/秒,假设网站内页平均大小为60KB…

C++数据类型、变量常量

个人主页:PingdiGuo_guo 收录专栏:C干货专栏 大家新年快乐,今天我们来学习C的数据类型,变量常量。 文章目录 1.数据类型的概念与思想 1.1基本数据类型 1.2复合数据类型 1.3类型修饰符 1.4类型转换 1.4.1static_cast 1.4.2…

【射影几何15】python双曲几何工具geometry_tools

目录 一、说明二、​环境问题:如何安装三、实现一个简单的例子四、绘制双曲组五、使用有限状态自动机加快速度六、资源和代码 一、说明 Geometry_tools 是一个 Python 包,旨在帮助您处理和可视化双曲空间和射影空间上的群动作。 该包主要构建在 numpy、…

【EAI 011】SayCan: Grounding Language in Robotic Affordances

论文标题:Do As I Can, Not As I Say: Grounding Language in Robotic Affordances 论文作者:Michael Ahn, Anthony Brohan, Noah Brown, Yevgen Chebotar, Omar Cortes, Byron David, Chelsea Finn, Chuyuan Fu, Keerthana Gopalakrishnan, Karol Hausm…