@Conditional 是 Spring 实现按需装配 Bean 的核心机制,其本质是通过 Condition 接口的 matches() 方法返回布尔值控制 Bean 注册;支持标注在 @Configuration、@Bean 或组件类上,多条件为“与”逻辑。

@Conditional 注解是 Spring 实现“按需装配 Bean”的核心机制,它让 Bean 的注册不再是无条件的,而是取决于运行时环境、配置、类路径或容器状态等具体条件。用得好,能避免冲突、提升模块可插拔性,也支撑了 Spring Boot 自动配置的整个体系。
理解 @Conditional 的基本逻辑
它的本质就是个“开关”:只有 matches() 方法返回 true,标注了 @Conditional 的类或方法才会被 Spring 容器处理并注册为 Bean;返回 false 就直接跳过,不加载、不实例化、不参与依赖注入。
你需要提供一个实现了 Condition 接口的类,重写 matches(ConditionContext context, AnnotatedTypeMetadata metadata) 方法:
- context 可获取 Environment(配置)、BeanFactory(已有 Bean)、ClassLoader(类加载器)等上下文信息
- metadata 可读取当前类或方法上所有注解的元数据,比如 @Bean 的参数、@Conditional 自身的属性等
用现成的条件注解快速实现常见场景
Spring Boot 已封装大量高频条件注解,无需手写 Condition 类,直接用更简洁安全:
立即学习“Java免费学习笔记(深入)”;
-
@ConditionalOnProperty:根据配置项开关功能
例如:@ConditionalOnProperty(prefix = "feature", name = "cache", havingValue = "true")—— 只有feature.cache=true时才装配缓存服务 -
@ConditionalOnClass / @ConditionalOnMissingClass:判断类是否在 classpath 中
常用于自动适配第三方库,如存在RedisTemplate类才启用 Redis 缓存配置 -
@ConditionalOnBean / @ConditionalOnMissingBean:检查容器中是否存在指定 Bean
典型用于“默认实现 + 允许覆盖”:只有用户没定义DataSource时,才自动装配 Hikari 默认数据源 -
@ConditionalOnExpression:支持 SpEL 表达式
例如:@ConditionalOnExpression("#{systemProperties['os.name'].toLowerCase().contains('win')}")—— Windows 环境下生效
自定义 Condition 实现灵活判断
当内置注解无法满足业务逻辑(比如需要结合多个配置+系统属性+运行时状态),就该自己写 Condition:
- 新建类实现
Condition接口,重写matches方法 - 在
@Conditional(YourCustomCondition.class)中引用它 - 示例场景:只在开发 profile 且数据库连接池未手动配置时启用嵌入式 H2 数据库
关键点在于充分利用 context.getEnvironment() 获取 active profiles 和 property,用 context.getBeanFactory().containsBean("xxx") 查容器状态,再组合判断逻辑。
注意装配时机和作用范围
@Conditional 可以标注在:
- @Configuration 类上:整个配置类及其内部所有 @Bean 都受该条件控制
- @Bean 方法上:仅该 Bean 是否注册受条件影响
- @Component / @Service 等组件类上:整个组件是否被扫描注册
多个 @Conditional 同时存在时,所有条件都必须为 true 才会装配——这是“与”逻辑,不是“或”。


















