Skip to content

Spring 中的 @Conditional 注解的作用是什么? ​

  • 标签:后端、Spring

🏛 业务架构师 ​

@Conditional 的作用是让 Bean 的注册带上条件:指定的 Condition 匹配才装配,否则跳过。Spring Boot 在它之上派生了一整套场景注解,构成自动配置的判断中枢:

  • @ConditionalOnClass:类路径有某类才生效(引了 Redis 依赖才装配 RedisTemplate);
  • @ConditionalOnMissingBean:容器没有同类型 Bean 才装配——框架给默认值、业务可覆盖的机制;
  • @ConditionalOnProperty:配置项满足条件才生效(开关式装配);
  • 还有 OnWebApplication、OnExpression、OnBean 等。

业务架构师视角,这个注解是**"按需供给、平滑扩展"的平台化基石**:

  1. 公司 starter 的标准姿势:我们封装统一日志/监控/多租户 starter 时,全部用条件装配——业务方引了依赖自动生效,想自定义就注册自己的 Bean 覆盖默认实现,平台与业务的扩展契约就靠 OnMissingBean 达成;
  2. 功能开关的装配级实现:@ConditionalOnProperty 让"灰度开关"控制的不只是运行时行为,连 Bean 是否存在都可控,省内存也省误触发;
  3. 多环境适配:同一套代码在有无 MQ、有无注册中心的环境下都能启动,交付物一份、环境差异内部消化。

需要业务化判断时还能自定义 Condition(比如"仅当租户数大于 N 才启用分库路由")。一句话:@Conditional 把"装配决策"代码化,是组件平台化必须掌握的能力。

🏗 系统架构师 ​

作用:按条件装配 Bean——条件类实现 Condition 接口,匹配才注册。@Profile 是它的特化;Spring Boot 自动配置整个建立在它的派生家族上:

  • @ConditionalOnClass:类路径存在某类才装配——starter 的核心:引依赖即生效;
  • @ConditionalOnMissingBean:用户未自定义才给默认——用户配置永远优先的开放性;
  • @ConditionalOnProperty(配置开关)、@OnWebApplication、@OnBean 等。

架构价值(重点讲):

  1. 它把「装配期决策」从运行期 if/else 提前到启动时——启动即确定形态,无运行时分枝开销,也让 Native AOT 成为可能(AOT 要求构建期确定装配结果);
  2. 条件装配是公司平台 starter 的机制基础:平台把日志、追踪、安全按条件(依赖存在加配置开关)统一注入,业务方零配置合规——这是平台工程的标准手法;
  3. 条件要可观测:--debug 输出条件评估报告,是排查「Bean 为什么没装配」的第一现场。

💻 全栈开发专家 ​

条件装配:满足条件才注册 Bean,是 Boot 自动配置的根基。

java
// 自定义条件:类路径有 XXL-JOB 且配置开关打开才启用
public class XxlJobEnabledCondition implements Condition {
    @Override
    public boolean matches(ConditionContext ctx, AnnotatedTypeMetadata meta) {
        return ctx.getClassLoader()
                   .getResource("com/xxl/job/core/XxlJobSpringExecutor.class") != null
            && ctx.getEnvironment().getProperty("xxl.job.enabled", Boolean.class, false);
    }
}

@Configuration
@Conditional(XxlJobEnabledCondition.class)
public class XxlJobConfig { }

Boot 在它之上派生了一整套场景注解,自动配置类里随处可见:

  • @ConditionalOnClass / @ConditionalOnMissingClass:类路径探测,避免硬依赖
  • @ConditionalOnMissingBean:用户没自定义才提供默认——用户配置优先的核心机制
  • @ConditionalOnProperty(havingValue/matchIfMissing)
  • @ConditionalOnBean、@ConditionalOnWebApplication

写自定义 starter 就是这套组合拳。排查"自动配置为什么没生效",启动加 --debug 看 ConditionEvaluationReport:Negative match 一栏写清卡在哪个条件——比如 @ConditionalOnClass 找不到类,多半是依赖没引或版本不对,这招排查 jar 冲突极快。