Spring Boot 自动配置原理?

2025年 阅读约 15 分钟 面试指南 · Spring Boot

深入解析Spring Boot自动配置原理:@SpringBootApplication注解拆解、@EnableAutoConfiguration工作机制、spring.factories SPI机制、@Conditional条件注解体系,附面试模拟问答。

一句话总结

Spring Boot 自动配置核心:@SpringBootApplication → @EnableAutoConfiguration → @Import(AutoConfigurationImportSelector) → 读取 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports → 加载所有自动配置类 → @Conditional 条件判断 → 按需装配 Bean。本质是 SPI 机制 + 条件注解 的组合,根据 classpath 中的 jar 依赖和配置,自动创建对应的 Bean,实现"约定大于配置"。

初级理解

@SpringBootApplication 拆解

# @SpringBootApplication 是一个组合注解 @SpringBootConfiguration # 本质是 @Configuration @EnableAutoConfiguration # 开启自动配置(核心) @ComponentScan( # 组件扫描 excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class) }) # 等价于同时标注了三个注解 # 1. @Configuration:标记为配置类 # 2. @EnableAutoConfiguration:开启自动配置 # 3. @ComponentScan:扫描当前包及子包的组件

自动配置做了什么?

# 没有 Spring Boot 时配置 DataSource # 需要手动写大量配置 @Bean public DataSource dataSource() { HikariDataSource ds = new HikariDataSource(); ds.setJdbcUrl("jdbc:mysql://localhost:3306/test"); ds.setUsername("root"); ds.setPassword("123456"); return ds; } # 有了 Spring Boot 自动配置 # 只需在 application.yml 中配置 spring: datasource: url: jdbc:mysql://localhost:3306/test username: root password: 123456 # DataSource、JdbcTemplate、TransactionManager 全部自动创建
一句话总结:自动配置 = 根据依赖和配置,自动创建 Bean,省去手动配置。

中级深入

AutoConfigurationImportSelector 源码

# 核心流程 # 1. @EnableAutoConfiguration 导入 AutoConfigurationImportSelector # 2. selectImports() 方法被调用 # 3. 读取 META-INF/spring/org.springframework.boot.autoconfigure # .AutoConfiguration.imports 文件 # 4. 获取所有自动配置类全限定名 # 5. 通过 @Conditional 过滤 # 6. 将符合条件的配置类导入容器 # 关键源码(简化) protected List<String> getCandidateConfigurations(...) { # 使用 SpringFactoriesLoader 加载 return SpringFactoriesLoader.loadFactoryNames( EnableAutoConfiguration.class, getBeanClassLoader() ); } # Spring Boot 2.7 之前:META-INF/spring.factories # Spring Boot 2.7 之后:META-INF/spring/ # org.springframework.boot.autoconfigure.AutoConfiguration.imports

@Conditional 条件注解体系

注解条件示例
@ConditionalOnClassclasspath 存在指定类有 HikariCP 才配 DataSource
@ConditionalOnMissingClassclasspath 不存在指定类没有某个类时启用备选
@ConditionalOnBean容器中存在指定 Bean有 DataSource 才配 JdbcTemplate
@ConditionalOnMissingBean容器中不存在指定 Bean用户没定义才用默认
@ConditionalOnProperty配置项有指定值spring.cache.type=redis
@ConditionalOnWebApplication是 Web 应用Web 环境才配 DispatcherServlet
中级要点:AutoConfigurationImportSelector 读取配置文件 → @Conditional 过滤 → 按需装配。

高级拓展

自动配置类示例:DataSourceAutoConfiguration

# DataSourceAutoConfiguration 源码分析 @AutoConfiguration # 标记为自动配置类 @ConditionalOnClass({DataSource.class, # classpath 有 DataSource EmbeddedDatabaseType.class}) @EnableConfigurationProperties( # 绑定配置属性 DataSourceProperties.class) @Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceCheckpointRestoreConfiguration.class}) public class DataSourceAutoConfiguration { @Configuration @ConditionalOnMissingBean(DataSource.class) # 用户没定义才创建 static class EmbeddedDatabaseConfiguration { @Bean DataSource dataSource(DataSourceProperties properties) { # 创建内嵌数据库(H2/Derby) } } @Configuration @ConditionalOnClass(HikariDataSource.class) # classpath 有 HikariCP @ConditionalOnMissingBean(DataSource.class) static class HikariDataSourceConfiguration { @Bean DataSource dataSource(DataSourceProperties properties) { # 创建 HikariCP 数据源 } } }

如何排除自动配置?

# 方式1:注解排除 @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class, RedisAutoConfiguration.class }) # 方式2:配置文件排除 spring: autoconfigure: exclude: - org.springframework.boot.autoconfigure.jdbc .DataSourceAutoConfiguration # 方式3:条件注解覆盖 # 自己定义同类型 Bean,@ConditionalOnMissingBean 会跳过自动配置 @Bean public DataSource dataSource() { # 自定义 DataSource }

实战场景

场景:自定义 Starter

# 1. 创建自动配置类 @AutoConfiguration @ConditionalOnClass(MyService.class) @EnableConfigurationProperties(MyProperties.class) public class MyAutoConfiguration { @Bean @ConditionalOnMissingBean public MyService myService(MyProperties properties) { return new MyService(properties.getUrl()); } } # 2. 创建配置文件 # META-INF/spring/org.springframework.boot.autoconfigure # .AutoConfiguration.imports # 内容: com.example.MyAutoConfiguration # 3. 创建属性类 @ConfigurationProperties(prefix = "my") public class MyProperties { private String url = "http://localhost:8080"; # getter/setter }

面试模拟

面试官:Spring Boot 自动配置原理是什么?

你:@SpringBootApplication 包含 @EnableAutoConfiguration,它通过 @Import 导入 AutoConfigurationImportSelector。该选择器读取 META-INF/spring/...AutoConfiguration.imports 文件获取所有自动配置类,然后通过 @Conditional 条件注解(如 @ConditionalOnClass、@ConditionalOnMissingBean)过滤,只装配符合条件的 Bean。本质是 SPI + 条件注解。

面试官:如何自定义一个 Starter?

你:三步:1)写自动配置类(@AutoConfiguration + @ConditionalOnClass + @Bean);2)在 META-INF/spring/...AutoConfiguration.imports 中注册;3)写属性类(@ConfigurationProperties)。引入 Starter 后自动配置生效。