Spring Boot中@ConditionalOnBean未检测到KafkaAutoConfiguration Bean问题
你遇到的问题核心是Spring Boot中组件扫描和自动配置类的加载顺序差异:
- 你的
MyKafkaProducer是用@Service标记的,会被Spring的@ComponentScan(默认扫描主类所在包及子包)提前处理。 KafkaAutoConfiguration属于Spring Boot的自动配置类,它的加载时机是在组件扫描完成之后,通过AutoConfigurationImportSelector批量导入并注册到BeanFactory中。
所以当Spring处理MyKafkaProducer上的@ConditionalOnBean(KafkaAutoConfiguration.class)条件时,KafkaAutoConfiguration还没被注册到容器里,条件判断不成立,自然不会创建这个Bean。
而改成@ConditionalOnMissingBean时,因为此时KafkaAutoConfiguration确实还不存在,条件成立,MyKafkaProducer被创建;之后自动配置类才被加载,所以两者最终都出现在Bean列表中。
针对你的需求(仅当Kafka自动配置生效时才创建MyKafkaProducer),推荐两种更靠谱的实现方式:
方案1:依赖KafkaAutoConfiguration中的实际Bean(更推荐)
既然你的MyKafkaProducer本身就依赖KafkaTemplate,而KafkaTemplate是KafkaAutoConfiguration中注册的核心Bean,直接把条件改成依赖KafkaTemplate更贴合实际需求,也能准确判断Kafka自动配置是否生效:
@Service @ConditionalOnBean(KafkaTemplate.class) @RequiredArgsConstructor public class MyKafkaProducer { private final KafkaTemplate<String, KafkaEntity> kafkaTemplate; // ... }
方案2:将自定义类转为自动配置类并指定加载顺序
如果你一定要基于KafkaAutoConfiguration本身做判断,可以把MyKafkaProducer的注册逻辑放到自动配置类中,并指定在KafkaAutoConfiguration之后加载:
- 创建自动配置类:
@Configuration @AutoConfigureAfter(KafkaAutoConfiguration.class) public class MyKafkaProducerAutoConfiguration { @Bean @ConditionalOnBean(KafkaAutoConfiguration.class) @RequiredArgsConstructor public MyKafkaProducer myKafkaProducer(KafkaTemplate<String, KafkaEntity> kafkaTemplate) { return new MyKafkaProducer(kafkaTemplate); } }
- 在项目的
META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件中添加该自动配置类的全限定名:
com.yourpackage.MyKafkaProducerAutoConfiguration
这样Spring会在加载完KafkaAutoConfiguration之后再处理你的自动配置类,此时@ConditionalOnBean(KafkaAutoConfiguration.class)就能正确识别到已经注册的配置类了。
内容的提问来源于stack exchange,提问作者Jiwon

