@ConditionalOnClass与@ConditionalOnMissingClass的区别是什么?
@ConditionalOnClass vs @ConditionalOnMissingClass in Spring Framework
这俩都是Spring Boot自动配置体系里的核心条件注解,作用都是根据类路径里有没有特定类来控制配置类或Bean的加载逻辑,但触发逻辑完全相反,具体区别可以从这几个维度看:
核心触发逻辑
- @ConditionalOnClass:只有当指定的类存在于当前项目的类路径中时,被它标注的配置类、Bean方法才会生效加载。
- @ConditionalOnMissingClass:只有当指定的类不存在于当前项目的类路径中时,被它标注的配置类、Bean方法才会生效加载。
典型使用场景
- @ConditionalOnClass:通常用来适配第三方依赖。比如项目引入了Redis的Jedis客户端依赖,才加载对应的Jedis配置;如果没引入,就跳过这个配置。
示例代码:@Configuration @ConditionalOnClass(Jedis.class) public class RedisJedisConfiguration { // 这里配置Jedis连接池、客户端等Bean } - @ConditionalOnMissingClass:用来提供默认实现兜底。比如项目没引入Jackson JSON库时,就启用框架自带的简易JSON处理器,避免因为缺少依赖导致功能失效。
示例代码:@Configuration @ConditionalOnMissingClass("com.fasterxml.jackson.databind.ObjectMapper") public class DefaultJsonConfig { @Bean public JsonProcessor defaultJsonProcessor() { return new SimpleJsonProcessor(); } }
参数写法差异
- @ConditionalOnClass:有两种写法——直接传类对象(
@ConditionalOnClass(Jedis.class)),或者传全类名字符串(@ConditionalOnClass("redis.clients.jedis.Jedis"))。用字符串的好处是不需要在编译时依赖这个类,适合一些可选依赖的场景。 - @ConditionalOnMissingClass:只能传全类名字符串(
@ConditionalOnMissingClass("com.fasterxml.jackson.databind.ObjectMapper"))。要是你直接传类对象,那如果这个类不存在的话,编译阶段就会报错,完全违背了它的设计初衷。
组合使用示例
实际开发中经常会把这俩注解组合起来,实现“有依赖用第三方实现,没依赖用默认实现”的灵活配置:
@Configuration public class JsonAutoConfig { // 当有Jackson时加载这个配置 @Configuration @ConditionalOnClass(ObjectMapper.class) static class JacksonJsonConfig { @Bean public JsonProcessor jacksonProcessor(ObjectMapper objectMapper) { return new JacksonJsonProcessor(objectMapper); } } // 没有Jackson时加载默认配置 @Configuration @ConditionalOnMissingClass("com.fasterxml.jackson.databind.ObjectMapper") static class DefaultJsonConfig { @Bean public JsonProcessor defaultProcessor() { return new SimpleJsonProcessor(); } } }
内容的提问来源于stack exchange,提问作者Balakirethiga R
相关产品推荐
相关产品推荐

