自动配置
自动配置(Auto-configuration)是 Spring Boot 的核心特性:根据类路径上存在的依赖、用户定义的 Bean 及配置属性,自动推断并注册合适的 Bean,无需手动写 XML 或 @Configuration。
触发入口
@SpringBootApplication
// ↑ 等价于以下三个注解的组合
@SpringBootConfiguration // 标记为配置类
@EnableAutoConfiguration // 开启自动配置(核心)
@ComponentScan // 扫描当前包及子包的组件
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}@EnableAutoConfiguration 触发 AutoConfigurationImportSelector,它负责从候选配置列表中筛选出当前环境适用的配置类并注册到容器。
加载机制
Spring Boot 3.x — .imports 文件
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
每行一个配置类全限定名,Spring Boot 启动时逐行读取:
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration
...(共 100+ 条)
Spring Boot 2.x — spring.factories
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfigurationSpring Boot 3.x 仍向后兼容
spring.factories,但新项目统一使用.imports文件。
自动配置类的结构
以 JacksonAutoConfiguration 为例,解析典型结构:
@AutoConfiguration // 标记为自动配置类(Spring Boot 3.x)
@ConditionalOnClass(ObjectMapper.class) // Jackson 在类路径上才生效
@ConditionalOnMissingBean(ObjectMapper.class) // 用户已定义则退出
public class JacksonAutoConfiguration {
@Bean
@ConditionalOnSingleCandidate(ObjectMapper.class)
public Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder(
JacksonProperties jacksonProperties,
ObjectProvider<Jackson2ObjectMapperBuilderCustomizer> customizers) {
// 根据 spring.jackson.* 属性构建 ObjectMapper
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
customizers.orderedStream().forEach(c -> c.customize(builder));
return builder;
}
}核心设计模式:先提供合理默认值,再通过 @ConditionalOnMissingBean 允许用户完全覆盖。
条件注解体系
自动配置类大量依赖条件注解决定是否生效:
| 注解 | 生效条件 |
|---|---|
@ConditionalOnClass | 类路径上存在指定类 |
@ConditionalOnMissingClass | 类路径上不存在指定类 |
@ConditionalOnBean | 容器中存在指定 Bean |
@ConditionalOnMissingBean | 容器中不存在指定 Bean(最常用于”默认可覆盖”) |
@ConditionalOnProperty | 配置属性满足条件 |
@ConditionalOnExpression | SpEL 表达式为真 |
@ConditionalOnWebApplication | 是 Web 应用(Servlet / Reactive) |
@ConditionalOnResource | 类路径 / 文件系统存在指定资源 |
@ConditionalOnJava | JVM 版本满足条件 |
@ConditionalOnSingleCandidate | 容器中只有一个候选 Bean |
完整用法详见 条件注解。
配置顺序控制
自动配置类之间可能存在依赖关系,通过以下注解控制顺序:
// 必须在 DataSourceAutoConfiguration 之后加载(保证 DataSource 已就绪)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
// 必须在 TransactionAutoConfiguration 之前加载
@AutoConfigureBefore(TransactionAutoConfiguration.class)
// 数字越小优先级越高(先加载)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@AutoConfigureAfter/@AutoConfigureBefore只影响自动配置类之间的顺序,不影响用户@Configuration类(用户 Bean 始终优先)。
调试自动配置
方法一:--debug 启动参数
java -jar app.jar --debug
# 或
./mvnw spring-boot:run -Dspring-boot.run.arguments=--debug输出 ConditionEvaluationReport,显示每个自动配置类的生效/跳过原因:
CONDITIONS EVALUATION REPORT
============================
Positive matches: ← 生效的配置
-----------------
JacksonAutoConfiguration matched:
- @ConditionalOnClass found required class 'com.fasterxml.jackson.databind.ObjectMapper'
Negative matches: ← 未生效的配置(及原因)
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory'
Exclusions: ← 被显式排除的配置
-----------
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
方法二:Actuator /actuator/conditions
management:
endpoints:
web:
exposure:
include: conditionscurl http://localhost:8080/actuator/conditions | jq .返回 JSON,包含每个配置类的匹配结果,便于程序化分析。
方法三:@SpringBootTest 中检查
@SpringBootTest
class AutoConfigurationTest {
@Autowired
private ApplicationContext context;
@Test
void shouldHaveJacksonBean() {
assertThat(context.containsBean("jacksonObjectMapper")).isTrue();
}
@Test
void shouldNotHaveRedisBean() {
assertThatThrownBy(() -> context.getBean(RedisConnectionFactory.class))
.isInstanceOf(NoSuchBeanDefinitionException.class);
}
}排除不需要的自动配置
方式一:注解排除
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class, // 不需要数据库
SecurityAutoConfiguration.class // 不需要 Spring Security
})
public class Application {}方式二:配置文件排除
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
- org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration用户配置 vs 自动配置的优先级
用户 @Configuration(最高优先级)
│
├── @Primary Bean(主候选)
├── @Bean 定义(覆盖自动配置)
└── @Component 扫描
│
自动配置(低优先级,通过 @ConditionalOnMissingBean 让步)
│
└── spring.factories / .imports 中声明的配置类
典型覆盖场景:
// 用户自定义 ObjectMapper,Jackson 自动配置检测到后不再注册默认的
@Configuration
public class JacksonConfig {
@Bean
@Primary
public ObjectMapper customObjectMapper() {
return Jackson2ObjectMapperBuilder.json()
.propertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
.build();
}
}自动配置与 Profile
自动配置类也可结合 @Profile 按环境生效:
@AutoConfiguration
@Profile("!test") // 非 test 环境才加载
@ConditionalOnClass(DataSource.class)
public class ProductionDataSourceAutoConfiguration {
// 生产数据源配置
}环境与 Profile 详见 环境与Profile。
自定义自动配置(编写 Starter)
编写自定义自动配置的完整流程:
// 1. 声明自动配置类
@AutoConfiguration
@ConditionalOnClass(MyService.class)
@ConditionalOnProperty(prefix = "my", name = "enabled",
havingValue = "true", matchIfMissing = true)
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService(MyProperties props) {
return new MyService(props);
}
}
// 2. 注册到 .imports 文件
// META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
// com.example.MyAutoConfiguration自定义 Starter 的完整步骤详见 自定义Starter。
常见自动配置类速查
| 自动配置类 | 触发条件 | 注册的核心 Bean |
|---|---|---|
DataSourceAutoConfiguration | 类路径有 JDBC 驱动 | DataSource(HikariCP) |
JpaRepositoriesAutoConfiguration | 类路径有 JPA | EntityManagerFactory、JpaTransactionManager |
WebMvcAutoConfiguration | Servlet + Spring MVC | DispatcherServlet、HandlerMapping |
SecurityAutoConfiguration | Spring Security 在类路径 | AuthenticationManager、默认过滤链 |
RedisAutoConfiguration | lettuce/jedis 在类路径 | RedisConnectionFactory、RedisTemplate |
RabbitAutoConfiguration | spring-amqp 在类路径 | ConnectionFactory、RabbitTemplate |
KafkaAutoConfiguration | spring-kafka 在类路径 | KafkaTemplate、ConsumerFactory |
CacheAutoConfiguration | @EnableCaching 存在 | CacheManager |
TaskExecutionAutoConfiguration | — | ThreadPoolTaskExecutor(默认 @Async 执行器) |
SchedulingAutoConfiguration | @EnableScheduling 存在 | TaskScheduler |
Spring Boot 4 变更(基于 Spring Framework 7)
Spring Boot 4 以 Spring Framework 7 + Java 21 为基线,自动配置机制在继承 3.x 架构的基础上有以下重要变化。
Java 21 最低要求
Spring Framework 7 / Spring Boot 4 将 Java 21 设为强制最低版本,低于 Java 21 无法编译运行。
这一变化带来的自动配置红利:
// 自动配置类可直接使用 Java 21 语法(Record、Pattern Matching、Sealed Classes)
@AutoConfiguration
@ConditionalOnClass(MyService.class)
public class MyAutoConfiguration {
// 使用 Record 作为轻量配置载体
public record ConnectionConfig(String host, int port, boolean ssl) {}
@Bean
@ConditionalOnMissingBean
public MyService myService(MyProperties props) {
var config = new ConnectionConfig(props.getHost(), props.getPort(), props.isSsl());
return new MyService(config);
}
}虚拟线程相关自动配置参见 虚拟线程。
spring.factories 彻底移除
Spring Boot 3.x 已废弃 spring.factories 中的 EnableAutoConfiguration 键,Spring Boot 4 完全移除该支持,只认 .imports 文件:
| 版本 | 自动配置注册方式 | spring.factories |
|---|---|---|
| Spring Boot 2.x | spring.factories | 完全支持 |
| Spring Boot 3.x | .imports 文件(推荐) | 兼容但已废弃 |
| Spring Boot 4.x | .imports 文件(唯一) | 不再支持 |
迁移检查:
# 扫描项目中是否还有旧的 spring.factories 自动配置声明
grep -r "EnableAutoConfiguration" src/main/resources/META-INF/spring.factories若有依赖的第三方 Starter 仍使用 spring.factories,需等待对方升级或自行 fork 迁移。
@Fallback — Bean 回退声明(Spring Framework 7 新增)
@Fallback 是 Spring Framework 7 引入的新注解,用于将一个 @Bean 标记为回退实现:当容器中存在其他同类型的非回退 Bean 时,该 Bean 自动被忽略;只有在没有任何非回退 Bean 时才生效。
它是 @ConditionalOnMissingBean 的声明式等价物,语义更清晰:
// Spring Boot 3.x 写法(命令式条件)
@Bean
@ConditionalOnMissingBean(PasswordEncoder.class)
public PasswordEncoder defaultPasswordEncoder() {
return new BCryptPasswordEncoder();
}
// Spring Boot 4.x 写法(声明式回退)
@Bean
@Fallback // 标记为回退 Bean
public PasswordEncoder defaultPasswordEncoder() {
return new BCryptPasswordEncoder();
}两者的关键区别:
| 对比 | @ConditionalOnMissingBean | @Fallback |
|---|---|---|
| 判断时机 | Bean 定义阶段(条件评估) | Bean 选择阶段(依赖注入时) |
| AOT 支持 | 需要额外 AOT hints | 原生支持,无需 hints |
| 适用范围 | 仅用于 @Bean 方法 | 也可用于 @Component 类 |
| 多回退候选 | — | 多个 @Fallback Bean 时保留所有(普通注入时报错需配合 @Primary) |
@Fallback 用于 @Component 类:
// 默认 HTTP 客户端实现,只在没有其他实现时才被装配
@Component
@Fallback
public class DefaultHttpClientAdapter implements HttpClientAdapter {
// ...
}
// 用户提供的自定义实现,会使 DefaultHttpClientAdapter 自动退出
@Service
public class OkHttpClientAdapter implements HttpClientAdapter {
// ...
}在自动配置类中混合使用:
@AutoConfiguration
@ConditionalOnClass(HttpClientAdapter.class)
public class HttpClientAutoConfiguration {
// 用户未自定义任何实现时,此 Bean 作为兜底
@Bean
@Fallback
public HttpClientAdapter defaultAdapter(HttpClientProperties props) {
return new DefaultHttpClientAdapter(props.getBaseUrl());
}
}AOT 处理增强(GraalVM Native Image)
Spring Boot 4 对 AOT(Ahead-of-Time)编译的支持更为成熟,自动配置类无需额外标注 @RegisterReflectionForBinding 等 hints,框架在编译期自动推断:
// Spring Boot 3.x:可能需要手动补充 AOT hints
@AutoConfiguration
@ImportRuntimeHints(MyAutoConfiguration.Hints.class)
public class MyAutoConfiguration {
static class Hints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
hints.reflection().registerType(MyService.class,
MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
MemberCategory.INVOKE_PUBLIC_METHODS);
}
}
}
// Spring Boot 4:框架自动推断,通常无需手动注册
@AutoConfiguration
public class MyAutoConfiguration {
// AOT hints 由框架根据 @Bean 方法签名自动生成
}条件注解在 AOT 模式下的行为:
// AOT 编译时,条件在编译期求值并固化
// @ConditionalOnClass 和 @ConditionalOnProperty 均可在 AOT 阶段处理
// @ConditionalOnBean / @ConditionalOnMissingBean 涉及运行时容器状态,
// AOT 处理时会保守地保留(不在编译期裁剪)
@AutoConfiguration
@ConditionalOnClass(DataSource.class) // AOT:编译期可确定,直接裁剪
@ConditionalOnProperty("app.db.enabled") // AOT:编译期可确定(属性固定时)
@ConditionalOnMissingBean(DataSource.class) // AOT:保守保留,运行时判断
public class CustomDataSourceAutoConfiguration { ... }GraalVM 原生编译详见 GraalVM原生编译。
条件注解新增:@ConditionalOnThreading
Spring Boot 4 新增 @ConditionalOnThreading,专门用于根据线程模型(平台线程 / 虚拟线程)决定是否装配:
// 只在虚拟线程模式下注册的执行器
@Bean
@ConditionalOnThreading(Threading.VIRTUAL)
public Executor virtualThreadExecutor() {
return Executors.newVirtualThreadPerTaskExecutor();
}
// 只在平台线程模式下注册的执行器
@Bean
@ConditionalOnThreading(Threading.PLATFORM)
public Executor platformThreadExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(8);
executor.initialize();
return executor;
}配合配置:
spring:
threads:
virtual:
enabled: true # true → Threading.VIRTUAL;false → Threading.PLATFORM版本对照速查
| 特性 | Spring Boot 2.x | Spring Boot 3.x | Spring Boot 4.x |
|---|---|---|---|
| 最低 Java 版本 | Java 8 | Java 17 | Java 21 |
| 自动配置注册 | spring.factories | .imports(推荐)/ spring.factories(兼容) | .imports 唯一 |
@AutoConfiguration | 无(用 @Configuration) | 引入 | 保持 |
@Fallback | 无 | 无 | 新增 |
@ConditionalOnThreading | 无 | 部分支持 | 完整支持 |
| AOT / Native | 实验性 | 正式支持 | 增强,hints 自动推断 |
| Jakarta EE 命名空间 | javax.* | jakarta.* | jakarta.* |
相关链接
- 条件注解 —
@ConditionalOnXxx全部注解详解 - 自定义Starter — 基于自动配置机制编写可复用 Starter
- 启动流程 — 自动配置在 Spring Boot 启动过程中的触发时机
- 属性绑定 —
@EnableConfigurationProperties与@ConfigurationProperties - 环境与Profile — 按 Profile 控制自动配置生效范围
- IOC与DI — Bean 注册、覆盖与
@Primary机制 - 虚拟线程 —
@ConditionalOnThreading与虚拟线程自动配置 - GraalVM原生编译 — AOT 编译与 Native Image 构建