Spring Boot 核心机制之 @Conditional:从原理到实战(一次讲透)

在使用 Spring Boot 的过程中,很多人会接触到:

  • @Conditional
  • @ConditionalOnProperty
  • @ConditionalOnClass

但往往只是"会用",却不知道它到底解决什么问题。

这篇文章帮你彻底搞清楚:

👉 @Conditional 到底是什么、什么时候触发、怎么用、适合用在哪

一、什么是 @Conditional(本质一句话)

👉 @Conditional = 条件装配机制

根据条件,决定某个 Bean 是否被加载到 Spring 容器中

二、先纠正一个常见误区(非常重要)

很多人第一反应是:

❌ 用来做环境切换(dev / test / prod)

👉 这是不准确的!

正确分工是:

功能 用什么
多环境切换 @Profile
条件装配 @Conditional

👉 举个对比:

环境切换(Profile)

java 复制代码
@Profile("dev")
@Bean
public ApiService mockApi() {}

条件控制(Conditional)

java 复制代码
@Bean
@ConditionalOnProperty(name = "feature.pay-enabled", havingValue = "true")
public PayService payService() {}

👉 总结一句:

Profile 控制"在哪个环境生效",Conditional 控制"这个功能有没有"

三、@Conditional 在启动流程中的位置(核心)

Spring 启动流程中:

java 复制代码
扫描类
    ↓
解析配置类
    ↓
⭐ 执行 @Conditional 判断
    ↓
注册 BeanDefinition
    ↓
创建 Bean

👉 关键点:

@Conditional 发生在"Bean 创建之前"

更准确一点:

扫描到类

检查 @Conditional

true → 注册 BeanDefinition

false → 直接跳过(相当于不存在)

四、核心原理(你必须理解)

@Conditional 本质是:

@Conditional(XXXCondition.class)

你要实现一个类:

java 复制代码
public class MyCondition implements Condition {

    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return true; // true 加载,false 不加载
    }
}

👉 这个 matches() 决定:

返回值 结果
true 加载 Bean
false 不加载

五、最常用的几个注解(你实际用这些)

Spring Boot 已经帮你封装好了:

1️⃣ @ConditionalOnProperty(最常用 ⭐)

java 复制代码
@Bean
@ConditionalOnProperty(name = "feature.pay-enabled", havingValue = "true")
public PayService payService() {}

yaml

java 复制代码
feature:
  pay-enabled: true

👉 作用:

配置开关控制功能是否开启

2️⃣ @ConditionalOnClass

@ConditionalOnClass(name = "com.mysql.cj.jdbc.Driver")

👉 用于自动配置(判断依赖是否存在)

3️⃣ @ConditionalOnMissingBean

@ConditionalOnMissingBean(PayService.class)

👉 如果没有 Bean 才创建(避免覆盖)

六、典型使用场景(企业真实用法)


✅ 1. 功能开关(最常见)

java 复制代码
feature:
sms-enabled: false
java 复制代码
@ConditionalOnProperty(name = "feature.sms-enabled", havingValue = "true")
@Bean
public SmsService smsService() {}

👉 效果:

  • false → 系统没有短信功能
  • true → 才有

✅ 2. 第三方接入控制

java 复制代码
pay:
wechat-enabled: true
java 复制代码
@ConditionalOnProperty(name = "pay.wechat-enabled", havingValue = "true")
@Bean
public WechatPayService wechatPayService() {}

✅ 3. 自动配置(Spring Boot 核心机制)

@AutoConfiguration

@ConditionalOnClass(DataSource.class)

👉 Spring Boot 就是这么"按需加载"的

七、一个非常关键的理解(必须记住)

👉 @Conditional 不是权限控制


❌ 错误理解

用户是 VIP → 用 @Conditional 控制 ❌


✅ 正确做法

第一层:系统能力(Conditional)

系统有没有 VIP 功能


第二层:用户权限(业务代码)

java 复制代码
if (user.isVip()) {
vipService.use();
}

👉 总结:

@Conditional 控制"系统有没有功能",不是"用户能不能用"

八、和 Android 的对比(帮助理解)

Android Spring
Flavor Profile
BuildConfig Environment
if 判断 @Conditional
不同 APK 不同 Bean

👉 本质差异:

类型 时机
Android Flavor 编译期
Spring Conditional 运行期(启动时)

九、实战推荐写法(你可以直接用)

feature:

pay-enabled: true

sms-enabled: false

vip-enabled: true

java 复制代码
@ConditionalOnProperty(name = "feature.pay-enabled", havingValue = "true")
@Bean
public PayService payService() {}

👉 搭配:

java 复制代码
@Autowired(required = false)
private PayService payService;

十、面试标准回答(直接背)

@Conditional 是 Spring 的条件装配机制,在容器启动时根据条件决定 Bean 是否注册。它通常用于功能开关、自动配置以及第三方组件加载。与 Profile 不同,Profile 主要用于环境切换,而 Conditional 更偏向于控制系统能力是否存在。


十一、总结(最重要)

@Conditional 的本质:

控制 Bean 是否存在

发生时机:

容器启动 → 注册 BeanDefinition 阶段

适用场景:

功能开关 / 自动配置 / 模块控制

不适用:

用户权限判断

核心理解

👉 @Conditional 不是控制"执行不执行"

👉 而是控制:

这个 Bean 在系统里"有没有"

下一篇:

AOP + 日志 + traceId 完整链路追踪(企业级模板)

内容包括:

  • 请求唯一 traceId
  • AOP 自动打印日志
  • 日志贯穿 Controller → Service → DB
  • 出问题一条链路查到底
相关推荐
石榴树下的七彩鱼2 小时前
智能抠图 API 接入实战:3 行代码实现图片自动去背景(Python / Java / PHP / JS)
java·图像处理·人工智能·python·php·api·抠图
知兀2 小时前
【Result类】(使用/不使用<T> data的情况);自带静态方法、纯数据类;
java·开发语言
Seven972 小时前
【从0到1构建一个ClaudeAgent】协作-自主Agent
java
洋不写bug2 小时前
Java线程(三):线程执行顺序问题、可重入锁、加锁操作解析,死锁解决
java·开发语言
huabiangaozhi2 小时前
跟据spring boot版本,查看对应的tomcat,并查看可支持的tomcat的版本范围
spring boot·后端·tomcat
fliter2 小时前
Rust 1.88 终于稳定了裸函数:写汇编不再需要那堆样板代码
后端
武子康2 小时前
大数据-271 Spark MLib-基础线性回归详解:从原理到损失优化实战
大数据·后端·spark
lifallen2 小时前
Flink Source / Sink Exactly-Once 边界分析
java·大数据·flink
AI服务老曹2 小时前
打破视频孤岛:基于 ZLMediaKit 的 GB28181 与 RTSP 统一接入网关架构设计
人工智能·spring boot·音视频