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

格式:键值对

properties 复制代码
# 2.x 示例
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration

2️⃣ 源码入口

java 复制代码
@EnableAutoConfiguration
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration { }

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

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

java 复制代码
@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 文件,不再解析键值对

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

3️⃣ 好处

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

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

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

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

1️⃣ 2.x 写法

复制代码
src/main/resources/META-INF/spring.factories

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.xxx.MyStarterAutoConfiguration

2️⃣ 3.x 写法

复制代码
src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

com.xxx.MyStarterAutoConfiguration

3️⃣ 条件示例

java 复制代码
@Configuration
@ConditionalOnClass(MyService.class)
@ConditionalOnMissingBean(MyService.class)
public class MyStarterAutoConfiguration {
    @Bean
    public 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 启动更快、冲突更少
相关推荐
vx_bscxy322几秒前
告别毕设焦虑!Python 爬虫 + Java 系统 + 数据大屏,含详细开发文档 基于web的图书管理系统74010 (上万套实战教程,赠送源码)
java·前端·课程设计
字节拾光录17 分钟前
Java工具库三足鼎立:Hutool、Apache Commons、Guava深度测评与场景化选型指南
java·apache·guava
javaの历练之路23 分钟前
基于 SpringBoot+Vue2 的前后端分离博客管理系统(含 WebSocket+ECharts)
spring boot·websocket·echarts
爱学习的小可爱卢24 分钟前
Java UDP编程实战:UDP数据报套接字编程DatagramPacket、DatagramSocket 、InetSocketAddress
java·udp·udp数据报
未来之窗软件服务26 分钟前
幽冥大陆(三十五)S18酒店门锁SDK go语言——东方仙盟筑基期
java·前端·golang·智能门锁·仙盟创梦ide·东方仙盟·东方仙盟sdk
大鸡腿同学35 分钟前
大量频繁记录有效击球方式
后端
r***934844 分钟前
【Redis】在Java中以及Spring环境下操作Redis
java·redis·spring
稚辉君1 小时前
Gemini永久会员 01不等概率随机到01等概率随机
后端
6***09261 小时前
如何快速搭建简单SpringBoot项目网页
java·spring boot·intellij-idea
z***56561 小时前
springboot整合mybatis-plus(保姆教学) 及搭建项目
spring boot·后端·mybatis