@EnableAutoConfiguration是 SpringBoot “约定优于配置” 理念的核心实现,也是@SpringBootApplication的核心组成部分。它的本质是根据项目依赖自动加载并配置符合条件的 Bean,无需开发者手动编写大量 XML 或 Java 配置。
一、先明确核心概念
1. 自动装配的目标
当你在pom.xml中引入spring-boot-starter-web依赖时,SpringBoot 会自动配置:
- Tomcat 容器(嵌入式);
- DispatcherServlet(SpringMVC 核心);
- CharacterEncodingFilter(字符编码过滤器);
- 视图解析器、消息转换器等;这些配置无需开发者手动声明,全部由
@EnableAutoConfiguration触发完成。
2. 核心注解关系
@SpringBootApplication
├── @SpringBootConfiguration(等价于@Configuration)
├── @ComponentScan(组件扫描)
└── @EnableAutoConfiguration(核心:自动装配)
└── @Import(AutoConfigurationImportSelector.class)(关键:导入自动配置选择器)
@EnableAutoConfiguration的核心能力来自于@Import(AutoConfigurationImportSelector.class)—— 这是自动装配的 “入口”。
二、自动装配的完整执行流程(核心)
用流程图先梳理整体逻辑,再拆解每个步骤:
graph TD
A[启动SpringBoot应用] --> B[@EnableAutoConfiguration生效]
B --> C[AutoConfigurationImportSelector.selectImports()]
C --> D[加载META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports]
D --> E[获取所有候选自动配置类(如WebMvcAutoConfiguration)]
E --> F[通过条件注解(@Conditional)过滤无效配置]
F --> G[将符合条件的配置类注入Spring容器]
G --> H[配置类中的@Bean生效,完成自动装配]
步骤 1:触发入口 ——AutoConfigurationImportSelector
@EnableAutoConfiguration通过@Import导入AutoConfigurationImportSelector,其核心方法是selectImports(),作用是筛选并返回需要自动配置的类全限定名。
核心源码简化(关键逻辑):
public class AutoConfigurationImportSelector implements DeferredImportSelector {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
// 1. 加载所有候选自动配置类
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
// 2. 返回过滤后的配置类数组
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
// 省略前置校验...
// 核心:获取所有候选自动配置类
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
// 核心:去重、排除(@SpringBootApplication的exclude属性)、过滤(条件注解)
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = getConfigurationClassFilter().filter(configurations);
// 触发自动配置事件(可扩展)
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
}
步骤 2:加载候选自动配置类 —— 核心文件
getCandidateConfigurations()方法会加载一个关键文件:
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
这个文件在spring-boot-autoconfigure包中,里面列出了所有 SpringBoot 内置的自动配置类(SpringBoot 2.7 + 版本,此前是META-INF/spring.factories)。
示例(部分内容):
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration
...
这些类就是 SpringBoot 为各种场景准备的 “预制配置类”。
步骤 3:条件过滤 —— 只加载符合条件的配置
加载所有候选配置类后,会通过条件注解过滤掉不符合当前环境的配置,核心是@Conditional系列注解:
| 条件注解 | 作用 |
|---|---|
| @ConditionalOnClass | 当类路径中存在指定类时,配置才生效(如 WebMvcAutoConfiguration 依赖 DispatcherServlet) |
| @ConditionalOnMissingClass | 当类路径中不存在指定类时生效 |
| @ConditionalOnBean | 当容器中存在指定 Bean 时生效 |
| @ConditionalOnMissingBean | 当容器中不存在指定 Bean 时生效(允许开发者自定义 Bean 覆盖默认配置) |
| @ConditionalOnProperty | 当配置文件中存在指定属性时生效(如server.port) |
| @ConditionalOnWebApplication | 当应用是 Web 应用时生效 |
示例:WebMvcAutoConfiguration 的条件过滤
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET) // 仅Servlet Web应用生效
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }) // 存在这些类才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class) // 无自定义WebMvc配置时生效
public class WebMvcAutoConfiguration {
// 自动配置DispatcherServlet、视图解析器等Bean
@Bean
public DispatcherServlet dispatcherServlet() {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
// ... 配置逻辑
return dispatcherServlet;
}
}
当你引入spring-boot-starter-web时,类路径中会包含DispatcherServlet,因此该配置类生效;若未引入,则该配置被过滤,不会加载。
步骤 4:注入有效配置类,完成自动装配
过滤后的配置类会被注入 Spring 容器,配置类中的@Bean方法会生成对应的组件(如 Tomcat、DispatcherServlet),最终完成自动装配。
三、关键特性:自定义覆盖默认配置
SpringBoot 自动装配的核心优势是 “允许开发者自定义配置覆盖默认值”,核心机制是@ConditionalOnMissingBean。
示例:覆盖默认的视图解析器
SpringBoot 自动配置了InternalResourceViewResolver,但如果你自定义了视图解析器 Bean,默认配置会失效:
// 自定义视图解析器
@Configuration
public class WebConfig {
@Bean
public ViewResolver myViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
原因:WebMvcAutoConfiguration中的视图解析器配置有@ConditionalOnMissingBean:
@Bean
@ConditionalOnMissingBean // 容器中无ViewResolver时才生效
public InternalResourceViewResolver defaultViewResolver() {
// 默认配置逻辑
}
四、如何控制自动装配(实战常用)
1. 排除指定自动配置类
通过@SpringBootApplication的exclude属性排除不需要的自动配置:
// 排除数据源自动配置(避免默认加载DataSource)
@SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
2. 通过配置文件关闭自动配置
在application.properties中配置:
# 关闭指定自动配置类
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration
3. 自定义自动配置类(扩展)
如果你想开发自己的 starter,可遵循以下步骤:
- 创建自动配置类(如
MyAutoConfiguration),使用@Conditional注解控制生效条件; - 在
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中添加该类的全限定名; - 打包为 starter 依赖,其他项目引入后即可自动装配。
示例自定义自动配置类:
@Configuration
@ConditionalOnClass(MyService.class) // 存在MyService时生效
@ConditionalOnProperty(prefix = "my.service", value = "enabled", matchIfMissing = true)
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService() {
return new MyService();
}
}
五、核心总结
- 核心入口:
@EnableAutoConfiguration通过@Import(AutoConfigurationImportSelector.class)触发自动装配; - 配置加载:从
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports加载所有候选自动配置类; - 条件过滤:通过
@Conditional系列注解(如@ConditionalOnClass、@ConditionalOnMissingBean)筛选有效配置; - 核心特性:“约定优于配置”,允许开发者通过自定义 Bean / 配置覆盖默认自动配置;
- 扩展能力:可通过
exclude排除自动配置,或自定义 starter 实现自己的自动配置逻辑。
简单来说,@EnableAutoConfiguration的本质是:SpringBoot 提前准备了大量配置类,根据项目依赖和条件注解,动态选择并加载符合当前环境的配置,无需开发者手动编写重复配置。这也是 SpringBoot “开箱即用” 的核心实现。

1370

被折叠的 条评论
为什么被折叠?



