Spring Boot 的自动配置是其核心特性之一,旨在根据应用的依赖和配置环境,自动完成 Bean 的创建与配置,减少开发者的手动配置工作。其核心思想是 “约定优于配置”,通过智能化的默认行为简化开发流程。
Spring Boot 通过 @Conditional
系列注解判断是否满足条件,只有满足条件时才会创建对应的 Bean。这是自动配置的基石。
条件注解 | 作用 |
---|---|
@ConditionalOnClass |
类路径中存在指定类时生效 |
@ConditionalOnMissingBean |
容器中不存在指定 Bean 时生效(避免覆盖用户自定义的 Bean) |
@ConditionalOnProperty |
配置文件中存在指定属性且匹配值时生效 |
@ConditionalOnWebApplication |
当前应用是 Web 应用时生效 |
@EnableAutoConfiguration
• 该注解通过 @Import(AutoConfigurationImportSelector.class)
触发自动配置逻辑。
• AutoConfigurationImportSelector
会从 META-INF/spring.factories
文件中加载所有预定义的自动配置类。
spring.factories
文件• 位于 META-INF
目录下,定义所有自动配置类的全限定名。
• Spring Boot 启动时会扫描所有 jar 包中的 spring.factories
,合并所有自动配置类。
• 示例(Spring Boot 内置的自动配置):
# spring-boot-autoconfigure/META-INF/spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
...
启动 Spring Boot 应用
• @SpringBootApplication
注解包含 @EnableAutoConfiguration
,触发自动配置逻辑。
加载 spring.factories
• 扫描所有依赖的 META-INF/spring.factories
,获取所有自动配置类。
过滤条件化配置
• 按 @Conditional
注解判断是否需要创建 Bean。例如:
◦ 如果类路径中存在 RedisOperations
类,则加载 RedisAutoConfiguration
。
◦ 如果用户未自定义 DataSource
Bean,则加载 DataSourceAutoConfiguration
。
按优先级排序
• 自动配置类按 @AutoConfigureOrder
或 @Order
注解排序,确保依赖关系正确。
创建并注册 Bean
• 符合条件的配置类中的 @Bean
方法被调用,生成的 Bean 注册到容器中。
RedisAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class) // 类路径存在 RedisOperations 时生效
@EnableConfigurationProperties(RedisProperties.class) // 绑定配置到 RedisProperties
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
@Bean
@ConditionalOnMissingBean(name = "redisTemplate") // 用户未定义时生效
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
• RedisProperties
类通过 @ConfigurationProperties
绑定 application.properties
中的 spring.redis.*
配置:
@ConfigurationProperties(prefix = "spring.redis")
public class RedisProperties {
private String host;
private int port;
// getters/setters
}
• 在 application.properties
中配置 Redis:
spring.redis.host=localhost
spring.redis.port=6379
• Spring Boot 会自动创建 RedisConnectionFactory
和 RedisTemplate
。
创建自动配置类
@Configuration
@ConditionalOnClass(MyService.class) // 依赖 MyService 类时生效
@EnableConfigurationProperties(MyServiceProperties.class)
public class MyServiceAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public MyService myService(MyServiceProperties properties) {
return new MyService(properties.getUrl());
}
}
定义配置属性类
@ConfigurationProperties(prefix = "my.service")
public class MyServiceProperties {
private String url = "default-url";
// getter/setter
}
注册自动配置类
• 在 META-INF/spring.factories
中添加:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyServiceAutoConfiguration
• 在 @SpringBootApplication
中排除:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class MyApp { ... }
• 通过配置文件禁用:
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
• 用户自定义的 Bean 会优先于自动配置的 Bean:
@Bean
public RedisTemplate<String, Object> redisTemplate() {
// 自定义实现
}
特性 | 自动装配(Autowiring) | 自动配置(Auto-Configuration) |
---|---|---|
目标 | 解决 Bean 之间的依赖关系 | 根据条件自动创建和配置 Bean |
实现方式 | 通过 @Autowired 和组件扫描 |
通过 @Conditional 和 spring.factories |
应用场景 | 所有 Spring 应用 | Spring Boot 特有 |
典型示例 | 注入 UserService 到 UserController |
自动配置 DataSource 、RedisTemplate |
问题 | 原因 | 解决方案 |
---|---|---|
自动配置未生效 | 缺少依赖或条件不满足 | 检查 @ConditionalOnClass 是否满足 |
自定义 Bean 未覆盖自动配置的 Bean | 未正确使用 @ConditionalOnMissingBean |
确保自定义 Bean 的名称或类型与自动配置一致 |
配置属性未绑定 | 未添加 @ConfigurationProperties |
检查属性类是否被 @EnableConfigurationProperties 扫描 |
application.properties
调整行为,而非直接修改自动配置类。@Conditional
避免冲突。--debug
参数,查看生效的配置类。Spring Boot 的自动配置通过条件化判断和约定优先的机制,大幅简化了应用的初始配置。其核心是 @Conditional
注解和 spring.factories
文件的协同工作。理解这一原理,可以帮助开发者高效利用默认配置,同时灵活定制个性化需求。