Spring Boot 自动配置原理深度解析
2024/1/18大约 3 分钟
Spring Boot 自动配置原理深度解析
什么是自动配置
Spring Boot 的自动配置(Auto-Configuration)是其核心特性之一,它能够根据类路径中的依赖自动配置 Spring 应用,大大简化了配置工作。
核心注解
@SpringBootApplication
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public @interface SpringBootApplication {
}这是一个组合注解,包含了三个重要注解:
- @SpringBootConfiguration: 标识这是一个配置类
- @EnableAutoConfiguration: 启用自动配置
- @ComponentScan: 扫描组件
@EnableAutoConfiguration
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}自动配置原理
1. 加载自动配置类
Spring Boot 通过 AutoConfigurationImportSelector 加载自动配置类:
public class AutoConfigurationImportSelector {
protected List<String> getCandidateConfigurations() {
return SpringFactoriesLoader.loadFactoryNames(
EnableAutoConfiguration.class,
getBeanClassLoader()
);
}
}2. 读取配置文件
从 META-INF/spring.factories 文件中读取配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
...3. 条件注解过滤
使用条件注解决定是否应用配置:
@Configuration
@ConditionalOnClass(DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
public class DataSourceAutoConfiguration {
// 配置逻辑
}常用条件注解
| 注解 | 说明 |
|---|---|
| @ConditionalOnClass | 类路径存在指定类时生效 |
| @ConditionalOnMissingClass | 类路径不存在指定类时生效 |
| @ConditionalOnBean | 容器中存在指定 Bean 时生效 |
| @ConditionalOnMissingBean | 容器中不存在指定 Bean 时生效 |
| @ConditionalOnProperty | 配置文件中存在指定属性时生效 |
| @ConditionalOnWebApplication | Web 应用时生效 |
自动配置示例
DataSource 自动配置
@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
}配置属性绑定
@ConfigurationProperties(prefix = "spring.datasource")
public class DataSourceProperties {
private String url;
private String username;
private String password;
// getters and setters
}自定义 Starter
1. 创建自动配置类
@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyProperties.class)
public class MyAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService(MyProperties properties) {
return new MyService(properties);
}
}2. 创建配置属性类
@ConfigurationProperties(prefix = "my.service")
public class MyProperties {
private String name;
private int timeout = 3000;
// getters and setters
}3. 创建 spring.factories
在 META-INF/spring.factories 中注册:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration调试自动配置
1. 启用 Debug 日志
debug=true2. 查看自动配置报告
启动应用后,控制台会输出:
- Positive matches: 生效的自动配置
- Negative matches: 未生效的自动配置
- Exclusions: 被排除的自动配置
- Unconditional classes: 无条件的自动配置
3. 使用 Actuator
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>访问 /actuator/conditions 查看条件评估报告。
排除自动配置
方法一:使用注解
@SpringBootApplication(exclude = {
DataSourceAutoConfiguration.class
})
public class Application {
}方法二:使用配置文件
spring.autoconfigure.exclude=\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration最佳实践
- 理解条件注解: 合理使用条件注解控制配置生效
- 提供默认配置: 为自定义 Starter 提供合理的默认值
- 配置属性前缀: 使用有意义的前缀避免冲突
- 文档完善: 为自定义 Starter 提供详细文档
- 测试充分: 编写单元测试和集成测试
总结
Spring Boot 自动配置通过约定优于配置的理念,大大简化了 Spring 应用的配置工作。理解其原理有助于:
- 更好地使用 Spring Boot
- 排查配置问题
- 开发自定义 Starter
- 优化应用启动性能