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

Spring Boot 自动配置:从 2.x 到 3.x 的进化之路


一、前言:为什么“零配置”能跑起来?

大多数 Spring Boot 开发者第一次新建项目时都会惊叹:

“我只写了一个 @SpringBootApplication,Tomcat、数据源、Redis 全都准备好了?”

这背后就是 自动配置(Auto-Configuration)。本文用 源码 + 图示 带你穿透原理,并对比 2.x 与 3.x 的关键差异


二、自动配置全景图(一张图秒懂)

┌─────────────┐        ┌──────────────────────┐
│ @SpringBootApp│─────▶│@EnableAutoConfiguration│
└────┬────────┘        └────┬─────────────────┘│                     ││           ┌─────────┴────────┐│           │AutoConfigurationImportSelector││           └────┬─────────────┘│                ││    ┌───────────┴──────────┐│    │读取候选配置类列表        ││    │(spring.factories 2.x) ││    │(.imports 3.x)         ││    └───────────┬──────────┘│                ││    ┌───────────┴──────────┐│    │条件注解过滤            ││    │@ConditionalOnClass... ││    └───────────┬──────────┘│                │
┌────┴──────────────┴────────────┐
│        BeanDefinitionRegistry    │
│        注册生效的自动配置类       │
└────────────────────────────────┘

三、2.x 实现细节(spring.factories 时代)

1️⃣ 文件位置与格式

文件:META-INF/spring.factories
格式:键值对

# 2.x 示例
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

2️⃣ 源码入口

@EnableAutoConfiguration
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration { }

AutoConfigurationImportSelector#selectImports 会解析上述文件,返回 String[] 候选类。

3️⃣ 条件过滤示例(DataSourceAutoConfiguration)

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(DataSource.class)
public class DataSourceAutoConfiguration {// 注册 DataSource Bean
}
  • @ConditionalOnClass:类路径存在指定类才生效
  • @ConditionalOnMissingBean:用户没写自己的 DataSource 才生效

四、3.x 实现细节(.imports 文件时代)

1️⃣ 文件位置与格式

文件:
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
格式:一行一个类名

# 3.x 示例
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

2️⃣ 源码差异

AutoConfigurationImportSelector 在 3.x 中改为读取 .imports 文件,不再解析键值对

// 伪代码
List<String> configurations = loadAutoConfigurationImports();
return configurations.toArray(new String[0]);

3️⃣ 好处

  • 启动更快:无需解析键值对
  • 文件更小:纯文本列表
  • 冲突更少:一个文件只放自动配置类

五、2.x vs 3.x 对比表

维度2.x3.x
配置文件spring.factoriesAutoConfiguration.imports
格式key=value一行一类名
加载效率需 split & trim直接读取
冲突解决多 key 冲突需合并无 key,天然无冲突
条件注解完全一致完全一致
用户自定义 Bean仍然优先(@ConditionalOnMissingBean)仍然优先

六、实战:如何自定义 Starter(兼容 2.x & 3.x)

1️⃣ 2.x 写法

src/main/resources/META-INF/spring.factoriesorg.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xxx.MyStarterAutoConfiguration

2️⃣ 3.x 写法

src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.importscom.xxx.MyStarterAutoConfiguration

3️⃣ 条件示例

@Configuration
@ConditionalOnClass(MyService.class)
@ConditionalOnMissingBean(MyService.class)
public class MyStarterAutoConfiguration {@Beanpublic MyService myService() {return new MyService();}
}

七、面试 30 秒答案

“Spring Boot 自动配置核心是 AutoConfigurationImportSelector 读取候选类列表,2.x 用 spring.factories 键值对,3.x 用 AutoConfiguration.imports 一行一类名,条件注解过滤后注册 Bean。3.x 启动更快、无键冲突。”


八、总结

  • 原理不变:条件注解 + 用户 Bean 优先
  • 文件变:2.x 键值对 → 3.x 纯列表
  • 性能升:3.x 启动更快、冲突更少
http://www.dtcms.com/a/303725.html

相关文章:

  • Python 程序设计讲义(28):字符串的用法——格式化字符串
  • 【C++】第十九节—一文万字详解 | AVL树实现
  • Go进阶:流程控制(if/for/switch)与数组切片
  • adb reboot 与 adb shell svc power reboot 的区别
  • 爬虫自动化:一文掌握 PyAutoGUI 的详细使用
  • 【RH134 问答题】第 9 章 访问网络附加存储
  • 智能制造的空间度量:机器视觉标定技术解析
  • 数据结构【红黑树】
  • 架构实战——互联网架构模板(“用户层”和“业务层”技术)
  • MySql插入中文生僻字/Emoji报错django.db.utils.DataError: (1366, “Incorrect string value
  • 14、distance_object_model_3d算子
  • Web3 网络安全漏洞的预防措施
  • 解决IDEA拉取GitLab项目报错:必须为访问令牌授予作用域[api, read user]
  • 风口还是伪命题?AI + Web3 赛道价值何在?
  • Time drifts can result in unexpected behavior such as time-outs.
  • IDEA中全局搜索快捷键Ctrl+Shift+F为何失灵?探寻原因与修复指南
  • imx6ull-驱动开发篇3——字符设备驱动开发实验
  • 【C++算法】79.BFS解决FloodFill算法_图像渲染
  • 【C#|C++】C#调用C++导出的dll之非托管的方式
  • 数据结构 排序(1)---插入排序
  • 基于mysql云数据库对比PowerBI vs QuickBI vs FineBI更换数据源的可行性
  • Kafka——Kafka控制器
  • 如何选择工业电脑?
  • 【VOS虚拟操作系统】未来之窗打包工具在前端资源优化中的应用与优势分析——仙盟创梦IDE
  • Spring AI集成Elasticsearch向量检索时filter过滤失效问题排查与解决方案
  • ICT模拟零件测试方法--晶体管测试
  • Linux救援模式之应用篇
  • 算法第29天|动态规划dp2:不同路径、不同路径Ⅱ、整数拆分、不同的二叉搜索树
  • PHP云原生架构:容器化、Kubernetes与Serverless实践
  • 【人工智能】OpenAI的AI代理革命:通向超拟人交互的未来之路