@ConditionalOnBean需精确匹配Bean,type按类型匹配更安全,name按ID匹配且大小写敏感;type与name互斥,优先用type传Class对象,多类型联合判断用type数组。

在Spring Boot自动配置中,@ConditionalOnBean注解需要精确匹配容器中已存在的Bean才能生效,选错名称或类型会导致条件不成立、配置被跳过,最终引发空指针或功能缺失。
@ConditionalOnBean的type和name属性区别
type属性接收Class>[]数组,用于按类型匹配Bean;name属性接收String[]数组,用于按Bean名称(ID)匹配。二者不能混用——【type和name互斥,同时指定时name会被忽略】。
用type更安全:Spring默认按类型注入,且多数场景下开发者不显式命名Bean,此时name无法命中。
用name仅适用于明确指定了@Bean(name="xxx")或@Component("xxx")的场景,比如多个同类型Bean需区分时。
选type:优先用Class对象而非字符串
方法一:直接传入目标Bean的Class类型
@ConditionalOnBean(type = DataSource.class)
这一步最常用,编译期可校验类是否存在,IDE能自动补全,不会因类名拼写错误导致条件失效。
方法二:用value属性等价写法(value是type的别名)
@ConditionalOnBean(value = {RedisTemplate.class, StringRedisTemplate.class})
注意:value和type语义完全一致,官方文档已将value标记为deprecated,新代码建议统一用type。
方法三:避免用name属性模拟type效果
错误写法:@ConditionalOnBean(name = "redisTemplate") —— 这只匹配名为"redisTemplate"的Bean,若实际Bean名是"stringRedisTemplate"或使用了@Bean(name="myRedis"),条件立刻失效。
选name:必须与容器注册时的ID完全一致
第一步:确认Bean的真实ID
查看定义处:@Bean注解是否带name参数;@Component/@Service是否带括号内名称;XML配置中的id属性。
第二步:验证ID是否被重命名
Spring Boot自动配置可能通过@Bean方法名或@ConditionalOnMissingBean的name覆盖原始ID,运行时用ApplicationContext.getBeanNamesForType(XXX.class)打印所有匹配ID。
第三步:严格按大小写和符号填写
@ConditionalOnBean(name = "userDetailsService") → 若实际ID是"userDetailService"(少一个s),条件不触发,且无编译报错。
【name值必须与getBean()第一个参数完全一致,包括大小写、下划线、驼峰格式】
多类型联合判断:用type数组一次检查多个
@ConditionalOnBean(type = {DataSource.class, JdbcTemplate.class})
该条件要求容器中**同时存在**这两个类型的Bean才生效,顺序无关,缺一不可。
不要写成两个独立注解叠加——Spring不支持同一方法上重复@ConditionalOnBean,会编译失败。
如果只需存在其中任一类型,请拆分为两个独立的@Bean方法,各自加对应的@ConditionalOnBean。

















