Spring Boot 自动配置原理
Spring Boot 自动配置原理
Spring Boot 最令人称道的特性是自动配置(Auto Configuration)——你只需引入一个 Starter,整个 Web 服务器、数据源、安全模块就能自动就绪。本文深入剖析这一魔法背后的机制。
@SpringBootApplication 注解组合
三个核心注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM,
classes = AutoConfigurationExcludeFilter.class)
})
public @interface SpringBootApplication {
// ...
}@SpringBootConfiguration:本质是@Configuration,表明这是一个配置类@ComponentScan:默认扫描启动类所在包及其子包中的@Component、@Service、@Repository、@Controller@EnableAutoConfiguration:启用自动配置,这是 Spring Boot 的魔法核心
@EnableAutoConfiguration 详解
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
// 指定要排除的自动配置类
Class<?>[] exclude() default {};
// 按名称排除
String[] excludeName() default {};
}关键在于 AutoConfigurationImportSelector。它实现了 DeferredImportSelector 接口,在 Spring 容器刷新阶段被调用,核心流程如下:
- 读取
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件 - 解析其中的全限定类名,加载这些自动配置类
- 根据
@Conditional*条件注解判断是否应该生效
自动配置文件的演变
Spring Boot 2.7 之前:spring.factories
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfigurationSpring Boot 2.7 之前使用 META-INF/spring.factories。
Spring Boot 3.x:新机制 AutoConfiguration.imports
Spring Boot 3.x 全面迁移到新的自动配置机制:
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
# 每个 Starter 提供一行,不使用反斜杠续行
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration新机制的优势:
- 按行解析,无需反斜杠续行,格式更清晰
- 按 Starter 分组,便于维护
- 支持条件过滤(
@ConditionalOnClass),缺失依赖时自动跳过
@Conditional 系列条件注解
自动配置类通过 @Conditional* 注解控制生效条件,这是”按需配置”的精髓。
常用条件注解
| 注解 | 作用 |
|---|---|
@ConditionalOnClass | 当 classpath 存在指定类时生效 |
@ConditionalOnMissingClass | 当 classpath 不存在指定类时生效 |
@ConditionalOnBean | 当容器中存在指定 Bean 时生效 |
@ConditionalOnMissingBean | 当容器中不存在指定 Bean 时生效 |
@ConditionalOnProperty | 当配置属性满足条件时生效 |
@ConditionalOnWebApplication | 当是 Web 应用时生效 |
一个真实例子
// DataSourceAutoConfiguration 部分源码
@AutoConfiguration(
after = { DataSourceTransactionManagerAutoConfiguration.class,
HibernateJpaAutoConfiguration.class }
)
@ConditionalOnClass({ DataSource.class, JdbcTemplate.class })
@ConditionalOnProperty(
prefix = "spring.datasource",
name = "url",
matchIfMissing = false // 如果没有配置 url 则不生效
)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
@Bean
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")
public DataSource dataSource(DataSourceProperties properties) {
// 创建 DataSource Bean
return properties.initializeDataSourceBuilder().build();
}
}当项目中引入了 spring-boot-starter-data-jpa 时,HikariDataSource 等类存在于 classpath,@ConditionalOnClass 通过,自动配置生效。同时,如果开发者已经手动定义了一个 DataSource Bean,@ConditionalOnMissingBean 生效,Spring Boot 不会覆盖你的定义。
自动配置的执行顺序
@AutoConfigureBefore / @AutoConfigureAfter
@AutoConfiguration
@AutoConfigureBefore(JdbcTemplateAutoConfiguration.class)
public class DataSourceAutoConfiguration {
// 此配置类会在 JdbcTemplateAutoConfiguration 之前执行
}@AutoConfigureOrder
控制同类配置类之间的相对顺序(数值越小越先执行)。
自定义 Starter
场景
假设你在多个项目中都需要复用一套统一的 JSON 处理逻辑,可以将其封装为一个自定义 Starter。
项目结构
my-common-starter/
├── src/main/java/com/example/mystarter/
│ └── MyAutoConfiguration.java
└── src/main/resources/META-INF/
└── spring/
└── org.springframework.boot.autoconfigure.AutoConfiguration.imports自动配置类
// MyAutoConfiguration.java
package com.example.mystarter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
@AutoConfiguration
@ConditionalOnClass(ObjectMapper.class) // 仅当 classpath 有 ObjectMapper 时生效
public class MyAutoConfiguration {
@Bean
@ConditionalOnClass(ObjectMapper.class)
public ObjectMapper customObjectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule()); // 注册 Java 8 时间模块
return mapper;
}
}AutoConfiguration.imports
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.mystarter.MyAutoConfiguration消费者使用
<dependency>
<groupId>com.example</groupId>
<artifactId>my-common-starter</artifactId>
<version>1.0.0</version>
</dependency>引入后,ObjectMapper 就会自动配置好 JavaTimeModule。
如何调试自动配置
启用 debug 日志
# application.yml
debug: true或启动参数:
java -jar app.jar --debug输出会显示每个自动配置类的生效状态(positive matches / negative matches)。
查看自动配置报告
启动时添加 --debug 后,日志中会打印:
=========================
AUTO-CONFIGURATION REPORT
=========================
Positive matches:
-----------------
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required class 'javax.sql.DataSource'
- @ConditionalOnProperty (spring.datasource.url) found property
Negative matches:
------------------
DataSourceAutoConfiguration did not match:
- @ConditionalOnClass did not find required class 'org.springframework.jdbc.datasource.DriverManagerDataSource'查看已注册的 Bean
@Autowired
ApplicationContext context;
@PostConstruct
public void listBeans() {
Arrays.stream(context.getBeanDefinitionNames())
.sorted()
.forEach(System.out::println);
}小结
Spring Boot 自动配置的核心机制:
AutoConfigurationImportSelector读取AutoConfiguration.imports文件加载配置类@Conditional*注解根据 classpath、Bean 存在性、配置文件动态判断是否生效- 开发者自定义的 Bean 优先级高于自动配置(通过
@ConditionalOnMissingBean实现) - 自定义 Starter 通过标准化的自动配置注册机制实现零配置复用
理解这一机制,你就能在需要时干预配置行为,写出更优雅的 Spring Boot 应用。
评论
Written by
AI-Writer
Related Articles
多环境配置与外部化配置
application-{profile}.yml 多环境切换、@ConfigurationProperties 强类型配置绑定、@Value 占位符、配置加密与自定义配置加载顺序
Read MoreSpring Boot 3 环境准备与项目初始化
搭建 Spring Boot 3.x 开发环境、使用 Spring Initializr 快速创建项目、理解 Maven/Gradle 构建配置、项目目录结构与第一个可运行应用
Read More依赖注入与 Bean 管理
深入理解 Spring IoC 容器核心概念、@Bean/@Component/@Configuration 注解使用、构造器注入与 Setter 注入、@Autowired 与 @Qualifier 精确注入、Bean 作用域与优先级控制
Read More