SpringBoot自动装配定义先后顺序失效原因极其解析
SpringBoot自动装配定义先后顺序失效原因极其解析
- 1、场景分析
- 1.1、问题总结
- 2、使用`@AutoConfigureBefore`、`@AutoConfigureAfter`和`@AutoConfigureOrder`注解指定加载顺序
- 2.2、@AutoConfigureXX注解失效原因总结
- 3、使用静态内部装配类提升加载顺序
- 4、bean加载顺序规则
1、场景分析
遇到的场景:
最近写定义依赖时,需要结合SpringMvc的WebMvcConfigurationSupport
扩展异常解析器方法extendHandlerExceptionResolvers
@Beanpublic HandlerExceptionResolver handlerExceptionResolver(@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager) {List<HandlerExceptionResolver> exceptionResolvers = new ArrayList<>();configureHandlerExceptionResolvers(exceptionResolvers);if (exceptionResolvers.isEmpty()) {addDefaultHandlerExceptionResolvers(exceptionResolvers, contentNegotiationManager);}extendHandlerExceptionResolvers(exceptionResolvers);HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();composite.setOrder(0);composite.setExceptionResolvers(exceptionResolvers);return composite;}
其中extendHandlerExceptionResolvers
方法提供了可继承的接口,让开发者能够添加自定义的异常解析器放到HandlerExceptionResolverComposite
中供dispatchServlet解析异常
1.1、问题总结
自定义的异常解析器配置类继承WebMvcConfigurationSupport
类重写extendHandlerExceptionResolvers
方法后,按照开放接口的原理,我们的异常解析器会添加到HandlerExceptionResolverComposite
列表中,但是实际上并非如此。
- 开发者自定义的装配类和
WebMvcConfigurationSupport
引用的jar包中装配类顺序 - 解决方案一:使用
@AutoConfigureBefore
、@AutoConfigureAfter
和@AutoConfigureOrder
注解指定加载顺序 - 解决方案二:使用静态内部装配类提前加载
2、使用@AutoConfigureBefore
、@AutoConfigureAfter
和@AutoConfigureOrder
注解指定加载顺序
SpringBoot下可以通过@Configuration自动扫描配置类和spring.factories来加载配置类,但这两种方式都无法控制加载顺序。
此时,可通过在配置类上增加@AutoConfigureAfter 、 @AutoConfigureBefore和@AutoConfigureOrder来控制配置文件加载的相对顺序。
SpringBoot的自动配置是通过spring.factories来指定的,它的优先级最低,加载时间最晚,spring.factories中的配置类顺序不代表实际加载顺序。可结合 @AutoConfigureAfter 和 @AutoConfigureBefore注解控制配置类的相对加载顺序。
通过@Configuration和@ComponentScan扫描加载的配置类,一般是我们自定义的配置类,这部分配置类优先级最高,加载时间最早,在加载spring.factories配置类前加载,但加载顺序不定。
这里就存在另一个易错点。简单的理解,当配置类在Spring扫描路径里面(scanBasePackages)会优先解析,后面在通过ImportSelector(spring.factories加载就是通过实现这个接口加载的配置类)加载进来的配置类就不会处理了,相当于一个类有两种加载方式,谁先加载谁就厉害。。。这里加载都会调用到processConfigurationClass()方法,这个下面会说!!!!
空口无凭上菜:ConfigurationClassParser–>doProcessConfigurationClass()方法加载顺序是@ComponentScan(扫描文件路径,路径里面元注解为@Component(@Cofiguration元注解也是@Component)都会被扫描到)—>加载@Import注解(配合ImportSelector接口)—>加载 @ImportResource—>加载@Bean—>…
大致顺序理清楚了。
也就是:通过spring.factories加载的配置类优先级更低,我们自定义的装配类最后才会加载
2.2、@AutoConfigureXX注解失效原因总结
extendHandlerExceptionResolvers
方法在WebMvcConfigurationSupport
加载的时候已经执行过了,由于加载顺序问题,那么我们自己的装配类中重写方法,将无法被调用;所以这就是@AutoConfigureBefore
、@AutoConfigureAfter
和@AutoConfigureOrder
注解无法生效的原因,不适用很多场景
3、使用静态内部装配类提升加载顺序
这也是小编使用的方法,这种场景在纯Spring环境下我们几乎遇不见,缘由是在Spring下所有的配置文件都是我们手动确定和编写,所以“哪些能写、哪些不能写,哪些在前,哪些在后”均是确定的,由我们程序员自行控制。该场景在Spring Boot场景下被大量用到
总结如下:
- static加在bean注册方法上
1、
@Configuration
配置类最优先被初始化,才会继续初始化其里面的@Bean;若有多个 @Configuration配置类,顺序由你构造AnnotationConfigApplicationContext
时传入的顺序为准(若是被scan扫描进去的,则无序)
2、 @Bean方法上加static成为静态方法,并不能提升此Bean的优先级
主要是因为@Bean的解析,必须是发生在@Configuration配置类被实例化后,因此它并不能提升优先级
- static加在静态内部类上
1、 @Configuration(外层)配置类的初始化顺序依旧是按照AnnotationConfigApplicationContext的定义顺序来的; 对于内部类的@Configuration的初始化(不管是静态还是非静态),也依旧是外部的@Configuration完成后才行
2、内部类里的@Bean的优先级均高于外层定义的@Bean,同时可以看到static静态内部类能够提升优先级,它比非静态内部类的优先级还高
3、内部类有限原则它只作用于本@Configuration类,也就是说仅在本主类内提升优先级。另外若出现多个内部类,按照定义顺序执行(static永远高于非static哦)
4、 内部类的访问权限无所谓,private都行。
4、bean加载顺序规则
直接上干货了,测试代码太长啦;
SpringBoot2.7以后自动装配的定义文件该成了org.springframework.boot.autoconfigure.AutoConfiguration.imports
- Spring.factories中定义的自动装配类优先级最低
- 本类中bean顺序按依赖优先+代码顺序原则,比如A/B/C三个Bean上中下顺序写的代码,A依赖了C,所以C比A和B都提前加载
- 跨类的bean加载顺序按照依赖优先+bean名称字母顺序加载
- 静态内部类bean与跨类bean加载顺序一致
相关文章:

SpringBoot自动装配定义先后顺序失效原因极其解析
SpringBoot自动装配定义先后顺序失效原因极其解析 1、场景分析1.1、问题总结 2、使用AutoConfigureBefore、AutoConfigureAfter和AutoConfigureOrder注解指定加载顺序2.2、AutoConfigureXX注解失效原因总结 3、使用静态内部装配类提升加载顺序4、bean加载顺序规则 1、场景分析 …...

API 集成测试工具Hitchhiker 0.1.1 正式发布
Hitchhiker 是一款开源的 Restful Api 集成测试工具,你可以在轻松部署到本地,和你的 team 成员一起管理 Api。 能做什么 * Team 协作开发 Api * Api 历史修改记录及支持 diff 展示 * 支持多环境变量及运行时变量 * 支持 Schedule 及批量 run * 不同…...

idea无法下载源码-Cannot download sources
问题: 解决方案:...

docker搭建mysql主从复制
1. 基础环境 环境 名称描述CentOS 7.6Linux操作系统版本docker 20.10.5docker版本mysql 8.0.29mysql镜像版本 节点 节点名称读写/主从地址端口master读节点/主节点192.168.1.6:3306slave1写节点/从节点192.168.1.6:3307slave2写节点/从节点192.168.1.6:3308 2. 主节点 使…...

在MacBook上实现免费的PDF文件编辑
之前我想对PDF文件进行简单处理(比如删页面、添空白页、调整页面顺序),要么是开wps会员【花钱贵】,下载(盗版)Adobe Acrobat【macOS不好下载】,要么用福昕阅览器登陆学生账号(学校买…...

QT第2课-GUI程序实例分析
GUI程序开发概述 不同的操作系统GUI开发原理相同不同的操作系统GUI SDK 不同 GUI 程序开发原理 GUI程序在运行时会创建一个消息队列系统内核将用户的键盘鼠标操作翻译成对应的程序消息程序在运行过程中需要实时处理队列中的消息当队列中没有消息时,程序将处于停滞…...

Android修行手册 - POI操作Excel常用样式(字体,背景,颜色,Style)
点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 👉关于作者 专注于Android/Unity和各种游戏开发技巧,以及各种资源分享&…...

Sprint Boot 学习路线 5
Spring MVC Spring MVC是Spring框架的一部分,是一个Web应用程序框架。它旨在使用Model-View-Controller(MVC)设计模式轻松构建Web应用程序。 在Spring MVC中,应用程序被分为三个主要组件:Model、View和Controller。M…...

git02->gui图形化界面使用,ssh协议,idea集成GIT
gui图形化界面使用ssh协议idea集成GIT 1.gui图形化界面使用 2.ssh协议 git/github生成密钥并通过 操作分为本地电脑配置和github网站配置 第一步:本地电脑配置 右键空白处,选择Git Bash Here打开相关命令窗口 1.配置用户名和邮箱(如果已经配…...
面向对象 元类 gil log 协程 垃圾回收 描述符 property
封装、继承、多态 当谈到封装、继承和多态时,通常是在面向对象编程 (OOP) 的上下文中讨论的。 封装 (Encapsulation) 示例: class Person: def __init__(self, name, age): self.__name = name # 使用双下划线前缀将属性变为私有 self.__age = age de…...

bibitem格式 添加参考文献
这次写论文时遇到一种bibitem格式的参考文献,latex中没有bib文件 分三步走 找到这篇文章的Bib Tex的引用,然后新建bib文件,命名为下图: 然后把Bib Tex引用的内容复制到上图的文件中,新建tex文件 内容为 \document…...
Leetcode 2934. Minimum Operations to Maximize Last Elements in Arrays
Leetcode 2934. Minimum Operations to Maximize Last Elements in Arrays 1. 解题思路2. 代码实现 题目链接:2934. Minimum Operations to Maximize Last Elements in Arrays 1. 解题思路 这一题思路上其实很简单,直接分情况考察一下最后一个元素交换…...

02:2440---时钟体系
目录 一:时钟控制 1:基本概念 2:时钟结构图 3:结构图分析 4:总线 5:寄存器 A:FCLK--MPLLCON B:HCLK和PCLK--CLKDIVN C:注意 二:上电复位 1:上电复位 2:时钟选择 三:代码 一:时钟控制 1:基本概念 S3C2440A中的时钟控制逻辑可以产生所需的时钟信号,包括C…...
SOEM源码解析——ecx_siiSM(读取SII的SM信息)
0 工具准备 1.SOEM-master-1.4.0源码1 ecx_siiSM函数总览 /** Get SM data from SII SM section in slave EEPROM.从SII的SM段获取SM信息* @param[in] context = context struct 句柄* @param[in] slave = slave number 从站序号* @param[out] SM = first SM str…...

【见缝插针】射击类游戏-微信小程序项目开发流程详解
还记得小时候玩过的见缝插针游戏吗,比一比看谁插得针比较多,可有趣了,当然了,通过它可以训练自己的手速反应,以及射击水平,把握时机,得分越高就越有成就感,相信小朋友们会喜欢它的&a…...
flutter开发实战-TweenSequence实现动画序列
flutter开发实战-TweenSequence实现动画序列 一、TweenSequence TweenSequence是允许创建一个Animation由一系列补间动画来确定值,每个TweenSequenceItem都有定义在动画的持续时间的权重确定动画间隔。 TweenSequence 动画组类TweenSequenceItem 用来定义每一个动…...

Flowable 外部表单
内置表单需要在每个节点中去配置,当如果多个节点使用同一套表单属性就要配置多次比较麻烦,修改的时候也要修改多次,外部表单可以定义一次,然后其它节点都去引用同一个表单属性。 外部表单需要定义一个.form后缀的文件。 外部表单…...

[mysql]索引优化-2
目录 一、分页查询优化1.根据自增且连续的主键排序的分页查询2.根据非主键字段排序的分页查询 二、Join关联查询优化1.嵌套循环连接 Nested-Loop Join(NLJ) 算法2.基于块的嵌套循环连接 Block Nested-Loop Join(BNL)算法 三、count(*)查询优化1.查询mysql自己维护的总行数2.sho…...

数据分析实战 | 泊松回归——航班数据分析
目录 一、数据及分析对象 二、目的及分析任务 三、方法及工具 四、数据读入 五、数据理解 六、数据准备 七、模型训练 八、模型评价 一、数据及分析对象 CSV文件:o-ring-erosion-only.csv 数据集链接:https://download.csdn.net/download/m0_7…...
Fliki AI:让视频创作更简单、更高效
在当今的数字时代,视频已经成为人们获取信息和娱乐的重要方式。无论是企业宣传、教育培训还是个人创作,视频都发挥着越来越重要的作用。然而,视频制作是一项复杂的工作,需要掌握一定的技能和经验。这对于初学者或没有专业视频制作…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器
——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的一体化测试平台,覆盖应用全生命周期测试需求,主要提供五大核心能力: 测试类型检测目标关键指标功能体验基…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
【生成模型】视频生成论文调研
工作清单 上游应用方向:控制、速度、时长、高动态、多主体驱动 类型工作基础模型WAN / WAN-VACE / HunyuanVideo控制条件轨迹控制ATI~镜头控制ReCamMaster~多主体驱动Phantom~音频驱动Let Them Talk: Audio-Driven Multi-Person Conversational Video Generation速…...
基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解
JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用,结合SQLite数据库实现联系人管理功能,并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能,同时可以最小化到系统…...
【Go语言基础【13】】函数、闭包、方法
文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数(函数作为参数、返回值) 三、匿名函数与闭包1. 匿名函数(Lambda函…...