跳到主要内容
Spring Boot 自动配置原理深度解析 | 极客日志
Java java
Spring Boot 自动配置原理深度解析 深入解析 Spring Boot 自动配置原理。内容包括约定优于配置优势、@SpringBootApplication 注解组合、@EnableAutoConfiguration 导入选择器机制、SpringFactoriesLoader 加载流程及 2.7+ 文件变化。详解条件注解控制生效逻辑,提供自定义 Starter 实现步骤与最佳实践,涵盖配置排除、启动报告查看及优先级设置,助力开发者掌握框架核心机制。
AiEngineer 发布于 2026/3/30 更新于 2026/5/22 26 浏览1. Spring Boot 核心优势
Spring Boot 的核心优势在于约定优于配置 ,它通过自动配置机制大幅简化了 Spring 应用的搭建和开发过程。
传统 Spring 开发需要大量 XML 配置或 Java Config:
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource () {
HikariConfig config = new HikariConfig ();
config.setJdbcUrl("jdbc:mysql://localhost:3306/test" );
config.setUsername("root" );
config.setPassword("123456" );
return new HikariDataSource (config);
}
@Bean
public SqlSessionFactory sqlSessionFactory () throws Exception {
SqlSessionFactoryBean factory = new SqlSessionFactoryBean ();
factory.setDataSource(dataSource());
return factory.getObject();
}
}
Spring Boot 只需引入依赖即可:
spring:
datasource:
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
2. @SpringBootApplication 解析
2.1 三个核心注解
SpringBootApplication {
Class<?>[] exclude() {};
String[] excludeName() {};
String[] basePackages() {};
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public
@interface
@ComponentScan(excludeFilters = {@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class), @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class)})
default
default
default
2.2 三个注解的作用 注解 作用 @SpringBootConfiguration标识这是一个 Spring Boot 配置类,等价于 @Configuration @EnableAutoConfiguration启用自动配置机制 @ComponentScan组件扫描,默认扫描当前包及其子包中的 @Component
3. @EnableAutoConfiguration 原理
3.1 注解定义 @Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String[] exclude() default {};
String[] excludeName() default {};
String[] value() default {};
}
3.2 自动配置导入选择器 @EnableAutoConfiguration 通过 @Import 导入 AutoConfigurationImportSelector,该类实现了 ImportSelector 接口:
public class AutoConfigurationImportSelector implements DeferredImportSelector , BeanClassLoaderAware, ResourceLoaderAware {
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
List<String> configurations = getAutoConfigurations(annotationMetadata);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, configurations);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
String[] autoConfigurations = configurations.toArray(new String [0 ]);
fireAutoConfigurationImportEvents(configurations, exclusions);
return autoConfigurations;
}
}
3.3 自动配置类加载流程
@SpringBootApplication 启动
扫描 @EnableAutoConfiguration
AutoConfigurationImportSelector.selectImports
SpringFactoriesLoader.loadFactoryNames
读取 META-INF/spring.factories 或 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
过滤不满足条件的配置类
返回需要导入的配置类
注册到 Spring 容器
4. 自动配置类加载机制
4.1 Spring Boot 2.7+ 变化 Spring Boot 2.7 之前使用 META-INF/spring.factories:
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
Spring Boot 2.7+ 推荐使用 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports:
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports (每行一个)
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
org.springframework.boot.autoconfigure.redis.RedisAutoConfiguration
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
4.2 Spring Boot 3.x Spring Boot 3.x 完全移除了 spring.factories,只支持 AutoConfiguration.imports 文件。
4.3 loadFactoryNames 实现 public abstract class SpringFactoriesLoader {
public static List<String> loadFactoryNames (Class<?> factoryType, @Nullable ClassLoader classLoader) {
String factoryTypeName = factoryType.getName();
Map<String, List<String>> result = loadSpringFactories(classLoader);
return result.getOrDefault(factoryTypeName, Collections.emptyList());
}
private static Map<String, List<String>> loadSpringFactories (@Nullable ClassLoader classLoader) {
if (cache.containsKey(classLoader)) {
return cache.get(classLoader);
}
Enumeration<URL> urls = classLoader.getResources("META-INF/spring.factories" );
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
Properties properties = PropertiesLoaderUtils.loadProperties(url);
result.addAll(properties);
}
cache.put(classLoader, result);
return result;
}
}
5. 自动配置条件注解 Spring Boot 使用条件注解控制配置类的生效条件。
5.1 常用条件注解 注解 作用 @ConditionalOnClass当 classpath 存在指定类时生效 @ConditionalOnMissingClass当 classpath 不存在指定类时生效 @ConditionalOnBean当容器中存在指定 Bean 时生效 @ConditionalOnMissingBean当容器中不存在指定 Bean 时生效 @ConditionalOnProperty当配置属性满足条件时生效 @ConditionalOnResource当资源存在时生效 @ConditionalOnWebApplication当是 Web 应用时生效
5.2 条件注解示例
@ConditionalOnClass(DruidDataSource.class)
@Configuration
public class DruidConfig {
@ConditionalOnMissingBean(DataSource.class)
@Bean
public DataSource dataSource () {
return new DruidDataSource ();
}
}
@ConditionalOnProperty(prefix = "spring.redis", name = "host")
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate (RedisConnectionFactory connectionFactory) {
return new RedisTemplate <>(connectionFactory);
}
}
@ConditionalOnWebApplication
@Configuration
public class WebMvcConfig {
}
5.3 条件注解原理 @Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(OnClassCondition.class)
public @interface ConditionalOnClass {
Class<?>[] value() default {};
String[] name() default {};
}
@Conditional 是 Spring 4.0 引入的通用条件注解,OnClassCondition 是其具体实现:
@Order(Ordered.HIGHEST_PRECEDENCE)
class OnClassCondition implements ConfigurationCondition {
@Override
public ConditionOutcome getMatchOutcome (ConditionContext context, AnnotatedTypeMetadata metadata) {
MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(ConditionalOnClass.class.getName());
List<Object> classesToCheck = attributes.get("value" );
for (Object classToCheck : classesToCheck) {
if (!ClassUtils.isPresent(classToCheck.toString(), context.getClassLoader())) {
return ConditionOutcome.noMatch("@ConditionalOnClass " + classToCheck + " not present" );
}
}
return ConditionOutcome.match();
}
}
6. 自动配置执行流程
6.1 SpringApplication 启动流程
SpringApplication.main()
createApplicationContext()
refresh(context)
invokeBeanFactoryPostProcessors()
处理 @Configuration 类的 @Bean
加载 AutoConfiguration
按条件过滤注册 AutoConfiguration Bean
ApplicationContext 准备完毕
6.2 配置类解析 Spring Boot 的自动配置类本质上是一个 @Configuration 类:
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(EmbeddedServletContainer.class)
@ConditionalOnWebApplication
@EnableConfigurationProperties(ServerProperties.class)
public class WebServerAutoConfiguration {
@Bean
@ConditionalOnMissingBean(TomcatServletWebServerFactory.class)
public TomcatServletWebServerFactory tomcatServletWebServerFactory () {
return new TomcatServletWebServerFactory ();
}
}
7. 自定义 Starter
7.1 命名规范 类型 命名规范 示例 官方 Starter spring-boot-starter-*spring-boot-starter-web第三方 Starter *-spring-boot-starterdruid-spring-boot-starter
7.2 实现步骤 @Configuration
@ConditionalOnProperty(prefix = "myapp", name = "enabled", havingValue = "true", matchIfMissing = true)
public class MyAppAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService () {
return new MyService ();
}
}
第二步:创建 spring.factories 或 imports 文件
# META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.example.myapp.MyAppAutoConfiguration
# META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports
com.example.myapp.MyAppAutoConfiguration
@ConfigurationProperties(prefix = "myapp")
public class MyAppProperties {
private String name = "default" ;
private int timeout = 3000 ;
}
@SpringBootApplication
@EnableConfigurationProperties(MyAppProperties.class)
public class Application {
public static void main (String[] args) {
SpringApplication.run(Application.class, args);
}
}
7.3 使用自定义 Starter
myapp:
enabled: true
name: my-app
timeout: 5000
@RestController
public class TestController {
@Autowired
private MyService myService;
@GetMapping("/test")
public String test () {
return myService.sayHello();
}
}
8. 自动配置源码层级
8.1 核心层级
Spring Boot 启动类
@SpringBootApplication
@EnableAutoConfiguration
AutoConfigurationImportSelector
SpringFactoriesLoader
META-INF/spring.factories / META-INF/spring/xxx.imports
加载所有 AutoConfiguration
@Conditional 条件过滤
实例化配置类
注册 Bean
8.2 配置类注册流程
public void refresh () {
invokeBeanFactoryPostProcessors(beanFactory);
finishBeanFactoryInitialization(beanFactory);
}
9. 常见自动配置类
9.1 DataSourceAutoConfiguration @Configuration(proxyBeanMethods = false)
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
@Configuration(proxyBeanMethods = false)
@Conditional(DataSourceAutoConfiguration.PooledDataSourceCondition.class)
@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
@Import(DataSourceConfiguration.Hikari.class)
protected static class Hikari {
}
}
9.2 RedisAutoConfiguration @Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public RedisTemplate<String, Object> redisTemplate (RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate <>();
return template;
}
@Bean
@ConditionalOnMissingBean
public StringRedisTemplate stringRedisTemplate (RedisConnectionFactory connectionFactory) {
return new StringRedisTemplate (connectionFactory);
}
}
9.3 WebMvcAutoConfiguration @Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication
@ConditionalOnClass({WebMvcConfigurer.class})
@EnableConfigurationProperties({WebMvcProperties.class})
@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
public class WebMvcAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public RequestMappingHandlerMapping requestMappingHandlerMapping (
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
}
}
10. 最佳实践
10.1 排除不需要的自动配置
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, RedisAutoConfiguration.class})
public class Application {
public static void main (String[] args) {
SpringApplication.run(Application.class, args);
}
}
spring:
autoconfigure:
exclude:
- org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
- org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration
10.2 查看自动配置报告
java -jar app.jar --debug
spring:
main:
log-startup-info: true
= = = = = = = = = = = = = = = = = = = = = = = = = AUTO- CONFIGURATION REPORT = = = = = = = = = = = = = = = = = = = = = = = = =
Positive matches :
DataSourceAutoConfiguration - @ConditionalOnClass found on class 'javax.sql.DataSource' (OnClassCondition)
- @ConditionalOnMissingBean (types: javax.sql.DataSource;SearchStrategy: all ) did not find any beans (OnBeanCondition)
Negative matches :
RedisAutoConfiguration - @ConditionalOnClass did not find 'org.springframework.data.redis.core.RedisOperations' (OnClassCondition)
10.3 自定义配置优先级
配置属性类 (最高优先级):application.yml 中配置
@Bean 定义 :代码中定义
自动配置默认值 :application.yml 未配置时使用
11. 总结 Spring Boot 自动配置是其核心优势,理解其原理对面试和开发都非常重要。
@SpringBootApplication 组合了 @Configuration、@EnableAutoConfiguration、@ComponentScan 三个注解
自动配置 通过 SpringFactoriesLoader 加载 META-INF/spring.factories 或 AutoConfiguration.imports 文件
条件注解 (@ConditionalOnClass、@ConditionalOnBean 等)控制配置类的生效条件
配置类 本质上是一个标注了 @Configuration 的普通 Spring 配置类
自定义 Starter 需要创建自动配置类和对应的配置文件
掌握这些知识点,能够帮助你更好地理解 Spring Boot 的工作原理,也能够自定义 Starter 封装公共组件。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online