@conditionalonclass 和 @conditionalonmissingbean 是 spring boot 防御性自动配置的核心注解:前者确保类存在才加载配置,后者仅在 bean 缺失时注册,二者常组合使用并配合 @conditionalonproperty 提升鲁棒性。

Spring Boot 中的 @ConditionalOnClass 和 @ConditionalOnMissingBean 是实现防御性组件配置的核心注解,它们分别从“依赖存在性”和“Bean 冗余风险”两个维度保护自动配置不被破坏——前者避免因类缺失导致启动失败,后者防止用户自定义 Bean 与框架默认 Bean 冲突引发异常。
用 @ConditionalOnClass 控制配置加载边界
这个注解确保只有当指定类出现在 classpath 时,相关配置才生效。它不是用来“兜底”,而是主动规避无依赖环境下的无效初始化。
- 典型场景:项目未引入
spring-webmvc,但你的自动配置类里写了@Bean public WebMvcConfigurer xxx() {...}—— 若不加@ConditionalOnClass(WebMvcConfigurer.class),应用直接启动失败 - 推荐写法:在
@Configuration类上标注,覆盖整个类中所有@Bean方法
(避免单个方法加注解后其他方法仍执行,造成资源浪费或副作用) - 注意:
value属性支持真实类型引用(即使该类当前不在 classpath,ASM 解析也允许),name属性则用于字符串类名(比如组合注解中必须用name)
用 @ConditionalOnMissingBean 防止 Bean 注册冲突
它不是“选一个”,而是“只在没人提供时我才出手”。这是 Spring Boot 自动配置可安全复用的关键机制。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- 核心逻辑:检查容器中是否已存在指定类型(或名称)的 Bean;若不存在,才注册当前
@Bean方法返回的实例 - 常见误用:把
@ConditionalOnMissingBean加在用户自定义配置类上 —— 此时它无法保证执行顺序,可能因用户 Bean 尚未注册而误判为“缺失” - 正确姿势:仅用于自动配置类(
@AutoConfigureBefore/@AutoConfigureAfter等配合使用),因为 Spring Boot 保证自动配置类在所有用户配置之后处理 - 示例:
@Bean@ConditionalOnMissingBean(DataSource.class)public DataSource hikariDataSource() { ... }
用户若已声明自己的DataSource,此默认数据源就不会注册,完全静默
组合使用提升配置鲁棒性
单一条件往往不够,真实场景需要叠加判断。例如一个缓存客户端自动配置:
- 先确认 Redis 相关类存在:
@ConditionalOnClass(RedisTemplate.class) - 再确认用户没自己提供
RedisTemplate:@ConditionalOnMissingBean(RedisTemplate.class) - 最后检查配置开关开启:
@ConditionalOnProperty(name = "spring.redis.enabled", havingValue = "true") - 三者同时满足,才注入默认
RedisTemplate实例 —— 任一条件不成立,都不执行,不报错、不干扰
避坑要点
这两个注解看似简单,但实际踩坑多集中在执行时机和作用范围上:
-
@ConditionalOnMissingBean对@Configuration类整体生效时,会跳过整个类注册;对单个@Bean方法生效时,只跳过该方法 —— 根据设计意图选择粒度 - 不要在同一个类里混用
@ConditionalOnBean和@ConditionalOnMissingBean判断同一类型,容易因注册顺序导致不可预测行为 - 若需根据多个类共同存在来启用配置,
@ConditionalOnClass支持传入数组:@ConditionalOnClass({A.class, B.class}) - 调试技巧:启动时加
--debug参数,Spring Boot 会输出所有被跳过的自动配置及原因,快速定位条件未满足的具体环节
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










