@Conditional 是 Spring Boot 条件化 Bean 装配的核心机制,需配合 Condition 接口实现类使用,通过 matches() 方法在容器刷新时动态决定是否注册 Bean;Spring Boot 提供 @ConditionalOnClass、@ConditionalOnMissingBean 等内置注解简化开发,也支持自定义 Condition 和 SpEL 表达式实现复杂逻辑。

@Conditional 是 Spring Boot 中实现条件化 Bean 装配的核心机制,它允许你根据运行时环境、配置、类路径或自定义逻辑决定是否创建某个 Bean。
理解 @Conditional 的基本用法
@Conditional 注解本身是一个元注解,需要配合一个实现了 Condition 接口的条件类使用。Spring 在刷新容器时会调用该条件类的 matches() 方法,返回 true 才注册对应 Bean。
- 条件类必须实现
org.springframework.context.annotation.Condition接口 -
matches()方法接收ConditionContext(提供环境、BeanFactory 等上下文)和AnnotatedTypeMetadata(注解元数据) - 可放在
@Bean方法、@Configuration类或@Component类上
常用内置条件注解(更简洁的写法)
Spring Boot 提供了大量开箱即用的 @Conditional* 注解,无需手写 Condition 类:
-
@ConditionalOnClass:类路径中存在指定类时生效(如@ConditionalOnClass(DataSource.class)) -
@ConditionalOnMissingBean:容器中不存在指定类型或名称的 Bean 时才注册(常用于自动配置兜底) -
@ConditionalOnProperty:配置项满足条件时生效(如@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")) -
@ConditionalOnExpression:SpEL 表达式为 true 时生效(如@ConditionalOnExpression("#{environment['spring.profiles.active'] == 'prod'}")) -
@ConditionalOnCloudPlatform:检测当前是否运行在特定云平台(如 AWS、Cloud Foundry)
自定义 Condition 实现复杂判断逻辑
当内置注解无法满足需求时,可编写自定义 Condition。例如:仅在 JVM 版本 ≥ 17 且系统属性 enable.feature 为 true 时加载 Bean:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
class JvmAndSystemPropertyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String javaVersion = System.getProperty("java.version");
boolean isJdk17OrHigher = javaVersion.startsWith("17") ||
javaVersion.startsWith("18") ||
javaVersion.startsWith("19") ||
javaVersion.startsWith("20");
String enableFeature = System.getProperty("enable.feature");
return isJdk17OrHigher && "true".equals(enableFeature);
}
}
然后在 Bean 方法上使用:
@Bean
@Conditional(JvmAndSystemPropertyCondition.class)
public MyService myService() {
return new MyService();
}
组合多个条件(AND / OR 逻辑)
@Conditional 默认是 AND 关系(多个 @Conditional 同时满足才生效)。若需 OR 逻辑,可封装到一个 Condition 实现中,或使用 @ConditionalOnExpression 手写 SpEL 表达式:
- 多个
@ConditionalOnProperty+@ConditionalOnClass同时标注 → 全部满足才加载 - OR 场景示例:
@ConditionalOnExpression("#{systemProperties['os.name'].contains('Windows') or systemProperties['os.name'].contains('Linux')}")
不复杂但容易忽略:条件判断发生在 ApplicationContext 刷新阶段,因此不能依赖尚未初始化的 Bean;若需访问配置属性,优先用 context.getEnvironment().getProperty(...) 而非 System.getProperty,更符合 Spring 配置管理规范。

















