全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-18 10 分钟 ✍️ juanwangdev

自动配置类的条件注解

条件注解是 Spring Boot 自动配置的核心机制,根据运行环境动态决定是否加载配置。

@Conditional 系列注解

核心注解一览

注解说明条件类型
@ConditionalOnClass类存在时生效类检测
@ConditionalOnMissingClass类不存在时生效类检测
@ConditionalOnBeanBean 存在时生效Bean 检测
@ConditionalOnMissingBeanBean 不存在时生效Bean 检测
@ConditionalOnProperty属性满足条件时生效属性检测
@ConditionalOnResource资源存在时生效资源检测
@ConditionalOnWebApplicationWeb 应用时生效应用类型
@ConditionalOnExpressionSpEL 表达式为真时生效表达式

@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说明
SERVLETServlet Web 应用
REACTIVEReactive 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 实现扩展条件逻辑

📝 发现内容有误?点击此处直接编辑

← 上一篇 监听器与事件机制
下一篇 → SSL/TLS性能优化
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库