@Conditional 是 Spring 条件化装配核心注解,依赖 Condition 接口实现类的 matches() 方法判断是否注册 Bean;支持自定义条件、内置注解(如 @ConditionalOnProperty)及组合条件(默认 AND,OR 需手动实现或用 SpEL)。

@Conditional 是 Spring 提供的条件化装配核心注解,它允许你根据自定义条件决定某个 Bean 是否被注册到 Spring 容器中。它的本质是:只有当指定的条件满足时,标注的类、方法或配置才会生效。
理解 @Conditional 的工作原理
该注解本身不包含逻辑,而是依赖一个实现了 Condition 接口 的条件类。Spring 在刷新容器(refresh)阶段,会调用这个条件类的 matches() 方法,返回 true 才装配,否则跳过。
你可以把它看作 Spring 的“开关”,而 Condition 实现类就是这个开关的判断规则。
快速实现一个自定义条件
步骤很简单:
- 写一个类实现
org.springframework.context.annotation.Condition接口 - 重写
matches(ConditionContext context, AnnotatedTypeMetadata metadata)方法 - 在需要条件装配的目标上加上
@Conditional(YourCondition.class)
例如,只在 JVM 参数中设置了 env=prod 时才加载生产数据库配置:
public class ProdEnvironmentCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return "prod".equals(System.getProperty("env"));
}
}
然后在配置类或 Bean 方法上使用:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
@Configuration
@Conditional(ProdEnvironmentCondition.class)
public class ProductionDataSourceConfig {
@Bean
public DataSource dataSource() { ... }
}
常用内置条件注解(更简洁的写法)
Spring 已为你封装了常见场景,无需手写 Condition 类:
- @ConditionalOnProperty:根据配置属性是否存在或值是否匹配(推荐用于环境开关)
- @ConditionalOnClass / @ConditionalOnMissingClass:根据类路径下是否存在某个类
- @ConditionalOnBean / @ConditionalOnMissingBean:根据容器中是否已有某类型 Bean
- @ConditionalOnWebApplication / @ConditionalOnNotWebApplication:判断是否为 Web 环境
比如启用 Redis 缓存 Bean,仅当项目引入了 redis.clients.jedis.Jedis 且配置了 cache.type=redis 时才装配:
@Bean
@ConditionalOnClass(Jedis.class)
@ConditionalOnProperty(name = "cache.type", havingValue = "redis")
public CacheManager redisCacheManager(RedisConnectionFactory factory) { ... }
组合多个条件(AND 逻辑)
@Conditional 默认是“与”关系:多个 @Conditional 同时存在时,全部返回 true 才装配。
如果要实现“或”逻辑,可以写一个复合 Condition 类,在 matches() 中手动 OR 多个判断;或者用 @ConditionalOnExpression 写 SpEL 表达式,例如:
@ConditionalOnExpression("#{systemProperties['env'] == 'prod' || systemEnvironment['HOME'] != null}")
注意:SpEL 表达式灵活但可读性略低,建议优先用语义明确的内置注解。

















