@ConditionalOnSingleCandidate要求类型匹配的候选Bean唯一或存在@Primary标记的首选Bean,其判断依据是Spring依赖注入的byType规则,而非简单计数;若多个同类型Bean均未标记@Primary,则条件不满足。

当Spring容器中某个类型只有一个候选Bean,或虽有多个但其中一个是【@Primary标记的首选Bean】时,@ConditionalOnSingleCandidate注解修饰的配置类或@Bean方法才会被加载。
判断逻辑详解
该注解不是简单统计Bean数量,而是按Spring依赖注入的“byType”匹配规则筛选候选者:先找出所有类型匹配的Bean,再排除被@ConditionalOnMissingBean等条件过滤掉的,最后看剩余候选是否唯一。
若存在多个同类型Bean且均未标记@Primary,条件不满足,配置直接跳过。
典型生效场景
方法一:容器中仅注册一个指定类型Bean
直接定义@Bean方法且未重复声明同类型Bean,此时@ConditionalOnSingleCandidate(UserService.class)自然成立。
方法二:多个Bean中设有一个@Primary
在多个UserService实现类中,对其中一个加@Primary注解,其余保持默认——此时该注解仍视为“单候选”,条件通过。
【注意:@Primary必须作用于具体Bean定义,而非接口或抽象类】
与@ConditionalOnBean的区别
第一步:@ConditionalOnBean只检查“是否存在”,不管有几个;
第二步:@ConditionalOnSingleCandidate进一步要求“存在且唯一(含@Primary兜底)”;
第三步:若你写@ConditionalOnSingleCandidate(DataSource.class),而项目里配了Hikari和Druid两个DataSource,又没标@Primary,整个配置块将被完全忽略,不会报错也不会加载。

















