![图片[1]-Spring Boot 自动配置靠什么实现?一文读懂 @Conditional 条件注解-速优课](https://www.suyouke.com/wp-content/uploads/2026/07/doubao_img_2304x1728_20260721_213959-1024x768.png)
很多人用Spring Boot的时候都有一个疑问:
为什么有些Bean会自动生效,有些却不会?
为什么加一个依赖,功能就“自动出现”了?
答案只有一个关键词:@Conditional
这篇文章,我们把Spring Boot条件注解的底层原理,一次讲透(建议收藏)
一、什么是 @Conditional?
一句话解释:
@Conditional = 按条件加载Bean
也就是说:
- 条件满足 → Bean生效
- 条件不满足 → Bean不加载
一个简单例子
@Bean
@Conditional(OnWindowsCondition.class)
public User user() {
return new User();
}
只有在Windows系统下,这个Bean才会生效。
本质就是:
把“if判断”写进Spring容器里
二、核心原理:Condition接口
所有条件注解的底层,都是实现这个接口
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
matches 方法
核心逻辑就在这里:
return true; // 加载Bean
return false; // 不加载
ConditionContext 能干嘛?
它可以拿到:
- BeanFactory
- Environment(配置)
- ClassLoader
- ResourceLoader
也就是说,你可以判断:
- 是否存在某个类
- 是否有某个配置
- 当前环境是什么
三、Spring Boot常用条件注解(重点)
Spring Boot帮我们封装了一堆“开箱即用”的条件注解:
1️⃣ @ConditionalOnClass
判断类是否存在
@ConditionalOnClass(name = "redis.clients.jedis.Jedis")
场景:
- 引入Redis依赖 → 自动配置生效
- 没引入 → 自动失效
2️⃣ @ConditionalOnMissingBean(超常用)
当容器中没有这个Bean时才生效
@ConditionalOnMissingBean(DataSource.class)
用途:
防止用户自定义Bean被覆盖
3️⃣ @ConditionalOnBean
只有存在某个Bean才生效
@ConditionalOnBean(DataSource.class)
4️⃣ @ConditionalOnProperty(企业最常用)
根据配置文件判断
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
application.yml:
feature:
enabled: true
常用于:
- 功能开关
- 灰度控制
5️⃣ @ConditionalOnExpression
支持SpEL表达式
@ConditionalOnExpression("'${env}'.equals('prod')")
6️⃣ @ConditionalOnResource
判断资源是否存在
@ConditionalOnResource(resources = "classpath:config.properties")
四、@Conditional在Spring Boot中的作用(重点)
核心一句话:
Spring Boot自动配置 = @Conditional 的大量使用
来看一个经典例子
@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {
}
逻辑是:
- 有 DataSource 类 → 自动配置数据库
- 没有 → 不配置
再看一个:
@Bean
@ConditionalOnMissingBean
public ObjectMapper objectMapper() {
return new ObjectMapper();
}
逻辑:
- 你没定义 → 我帮你创建
- 你定义了 → 用你的
这就是:
Spring Boot“智能”的核心原因
五、源码执行流程(面试重点)
在 Spring 容器启动时:
会执行:
ConditionEvaluator.shouldSkip()
核心逻辑:
1️⃣ 扫描所有带 @Conditional 的类或方法
2️⃣ 调用 Condition.matches()
3️⃣ 返回 false → 跳过Bean加载
所以你可以这样理解:
@Conditional = Bean加载的“开关控制器”
六、自定义一个条件注解(实战)
我们自己实现一个
第一步:实现 Condition
public class OnLinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String os = context.getEnvironment().getProperty("os.name");
return os != null && os.contains("Linux");
}
}
第二步:使用
@Bean
@Conditional(OnLinuxCondition.class)
public User user() {
return new User();
}
只有Linux环境才加载。
七、常见面试问题
Q1:Spring Boot自动配置原理?
答:
- 基于 @EnableAutoConfiguration
- 通过 spring.factories 加载配置类
- 使用 @Conditional 控制是否生效
Q2:@Conditional 和 @Profile 区别?
@Profile:
- 只针对环境(dev/test/prod)
@Conditional:
- 更灵活,可以判断任意条件
Q3:为什么需要 @ConditionalOnMissingBean?
防止:
自动配置覆盖用户自定义配置
八、实战总结(重点记住)
Spring Boot核心三板斧:
1.自动配置(AutoConfiguration)
2.条件装配(@Conditional)
3.SPI机制(spring.factories)
而 @Conditional 就是:
让Spring Boot“聪明”的关键机制
九、写在最后
很多人只会用Spring Boot,但真正拉开差距的是:
是否理解底层原理
当你理解了 @Conditional,你就能:
- 自定义自动配置
- 做框架扩展
- 写更优雅的系统
技术的本质不是会用,而是能解释“为什么”。








请登录后查看评论内容