自动配置类的条件注解
条件注解是 Spring Boot 自动配置的核心机制,根据运行环境动态决定是否加载配置。
@Conditional 系列注解
核心注解一览
| 注解 | 说明 | 条件类型 |
|---|---|---|
| @ConditionalOnClass | 类存在时生效 | 类检测 |
| @ConditionalOnMissingClass | 类不存在时生效 | 类检测 |
| @ConditionalOnBean | Bean 存在时生效 | Bean 检测 |
| @ConditionalOnMissingBean | Bean 不存在时生效 | Bean 检测 |
| @ConditionalOnProperty | 属性满足条件时生效 | 属性检测 |
| @ConditionalOnResource | 资源存在时生效 | 资源检测 |
| @ConditionalOnWebApplication | Web 应用时生效 | 应用类型 |
| @ConditionalOnExpression | SpEL 表达式为真时生效 | 表达式 |
@ConditionalOnClass
使用示例
Java
@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {
@Bean
public DataSource dataSource() {
return new HikariDataSource();
}
}
条件实现
Java
public class OnClassCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 获取注解属性
MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(
ConditionalOnClass.class.getName());
for (String className : attributes.get("value")) {
try {
// 检查类是否可加载
Class.forName(className);
} catch (ClassNotFoundException e) {
return false; // 类不存在,条件不满足
}
}
return true;
}
}
@ConditionalOnMissingBean
防止重复配置
Java
@Configuration
public class WebMvcAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
return filter;
}
}
条件匹配逻辑
Java
public class OnBeanCondition extends SpringBootCondition {
@Override
protected boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 检查 BeanFactory 是否已存在指定 Bean
String[] beanNames = getBeanNames(context.getBeanFactory());
return beanNames.length == 0; // 不存在则匹配
}
}
@ConditionalOnProperty
属性条件配置
Java
@Configuration
@ConditionalOnProperty(name = "cache.enabled", havingValue = "true", matchIfMissing = false)
public class CacheAutoConfiguration {
@Bean
public CacheManager cacheManager() {
return new RedisCacheManager();
}
}
参数说明
| 参数 | 说明 |
|---|---|
| name | 属性名 |
| havingValue | 期望值 |
| matchIfMissing | 属性不存在时是否匹配 |
条件实现
Java
public class OnPropertyCondition extends SpringBootCondition {
@Override
protected boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
String propertyName = attributes.get("name");
String havingValue = attributes.get("havingValue");
boolean matchIfMissing = attributes.getBoolean("matchIfMissing");
String propertyValue = env.getProperty(propertyName);
if (propertyValue == null) {
return matchIfMissing;
}
return propertyValue.equals(havingValue);
}
}
@ConditionalOnWebApplication
Web 应用检测
Java
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
public class ServletWebServerFactoryAutoConfiguration {
@Bean
public TomcatServletWebServerFactory tomcatServletWebServerFactory() {
return new TomcatServletWebServerFactory();
}
}
Type 类型
| Type | 说明 |
|---|---|
| SERVLET | Servlet Web 应用 |
| REACTIVE | Reactive Web 应用 |
| ANY | 任意 Web 应用 |
@ConditionalOnExpression
SpEL 表达式条件
Java
@Configuration
@ConditionalOnExpression("${feature.enabled} and ${feature.level} >= 2")
public class FeatureAutoConfiguration {
@Bean
public FeatureService featureService() {
return new FeatureServiceImpl();
}
}
组合条件注解
多条件组合
Java
@Configuration
@ConditionalOnClass(RedisClient.class)
@ConditionalOnProperty(name = "spring.redis.enabled", havingValue = "true")
@ConditionalOnMissingBean(RedisTemplate.class)
public class RedisAutoConfiguration {
@Bean
public RedisTemplate<String, Object> redisTemplate() {
return new RedisTemplate<>();
}
}
条件顺序
所有条件按注解顺序依次检查,任一条件不满足则跳过整个配置类。
自定义条件注解
自定义 Condition
Java
public class OnFeatureEnabledCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment env = context.getEnvironment();
String feature = env.getProperty("app.feature");
// 自定义条件逻辑
return "premium".equals(feature);
}
}
自定义注解
Java
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Conditional(OnFeatureEnabledCondition.class)
public @interface ConditionalOnFeatureEnabled {
String value() default "";
}
使用自定义注解
Java
@Configuration
@ConditionalOnFeatureEnabled("premium")
public class PremiumFeatureConfiguration {
@Bean
public PremiumService premiumService() {
return new PremiumServiceImpl();
}
}
条件评估报告
启用条件报告
YAML
debug: true # 或 --debug 启动参数
查看报告
text
启动时输出 CONDITIONS EVALUATION REPORT
============================
Positive matches:
DataSourceAutoConfiguration matched:
- @ConditionalOnClass found required classes (DataSource)
Negative matches:
RedisAutoConfiguration did not match:
- @ConditionalOnClass did not find required class (RedisClient)
注意:条件注解只在配置类解析阶段执行一次,不影响运行时性能。
要点总结
- @ConditionalOnClass 根据类是否存在决定加载
- @ConditionalOnMissingBean 防止重复 Bean 注册
- @ConditionalOnProperty 根据配置属性控制
- 条件注解可组合使用,顺序依次检查
- 可自定义 Condition 实现扩展条件逻辑
📝 发现内容有误?点击此处直接编辑