Spring Boot 自动配置原理
Spring Boot 自动配置的核心是通过条件化配置(@Conditional)实现。当满足特定条件时,相关的 Bean 会被自动加载到 Spring 容器中。
自动配置的触发依赖于 spring-boot-autoconfigure 模块中的 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件。该文件列出了所有自动配置类,Spring Boot 在启动时会加载这些配置类。
每个自动配置类通常包含以下内容:
@Configuration注解标记为配置类@ConditionalOnClass、@ConditionalOnProperty等条件注解控制是否生效@EnableConfigurationProperties绑定外部配置@Bean方法定义需要自动配置的 Bean
例如数据库自动配置:
java
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
public class DataSourceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public DataSource dataSource(DataSourceProperties properties) {
return properties.initializeDataSourceBuilder().build();
}
}
自定义 Starter 开发步骤
创建自定义 Starter 需要两个模块:
- 自动配置模块(包含核心逻辑)
- Starter 模块(仅包含依赖)
自动配置模块开发
创建配置类:
java
@Configuration
@ConditionalOnClass(MyService.class)
@EnableConfigurationProperties(MyServiceProperties.class)
public class MyServiceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService(MyServiceProperties properties) {
return new MyService(properties.getPrefix());
}
}
定义配置属性类:
java
@ConfigurationProperties("my.service")
public class MyServiceProperties {
private String prefix = "default";
// getters and setters
}
在 resources/META-INF 下创建:
spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件,内容为自动配置类的全限定名additional-spring-configuration-metadata.json用于配置提示
Starter 模块开发
Starter 只需包含对自动配置模块的依赖:
XML
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-service-autoconfigure</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
最佳实践
命名规范遵循 {name}-spring-boot-starter 格式。例如自定义缓存 Starter 可命名为 cache-spring-boot-starter。
提供明确的配置元数据,帮助用户了解可用配置项:
json
{
"properties": [{
"name": "my.service.prefix",
"type": "java.lang.String",
"description": "Prefix for service output.",
"defaultValue": "default"
}]
}
测试自动配置:
java
@SpringBootTest
public class MyServiceAutoConfigurationTests {
@Autowired(required = false)
private MyService myService;
@Test
void serviceAutoConfigured() {
assertThat(myService).isNotNull();
}
}
调试技巧
启动时添加 --debug 参数可查看自动配置报告:
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches:
-----------------
MyServiceAutoConfiguration matched
- @ConditionalOnClass found required class 'com.example.MyService'