如何让@SpringBootTest环境下的@ConditionalOnMissingBean注解正常生效?
看起来你遇到的问题挺典型的:主应用启动时@ConditionalOnMissingBean好好的,一跑SpringBoot测试就失效,导致两个同类型Bean冲突。这种情况大多和测试上下文的配置加载顺序、配置类的类型有关,给你几个实用的解决思路:
强制自定义Bean先注册,控制配置加载顺序
库中的LibConfig如果是普通的@Configuration类(不是SpringBoot自动配置类),它和你应用里的ServiceConfig的加载顺序可能是随机的——主应用里刚好是你的配置先被扫到,所以条件注解生效;但测试环境里顺序反转了,库的Bean先被创建,之后你的Bean也注册,就撞车了。
解决办法很简单:在你的ServiceConfig上加上@AutoConfigureBefore(LibConfig.class),强制让应用的配置类先被处理。这样当Spring处理LibConfig时,RequestHeaderSetter已经存在,条件注解就会跳过库中Bean的创建。把库的配置改成SpringBoot自动配置类(如果能改库代码的话)
如果库的LibConfig不是自动配置类,建议把它改成自动配置类。具体操作是在库的resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports文件里,加上LibConfig的全类名。SpringBoot会自动保证自动配置类在用户自定义配置之后加载,这样@ConditionalOnMissingBean就能准确检测到你已经定义的Bean,不会重复创建。排查测试环境的额外配置
检查下你的integrationTest配置文件或者测试类,有没有重复引入LibConfig的情况——比如是不是用@Import或者@TestConfiguration又导了一遍库的配置?另外也确认下测试类的包路径和主应用是否一致,避免扫描到重复的配置类。在测试里明确指定要加载的配置类
如果上面的方法都不管用,可以在@SpringBootTest里显式指定要加载的配置类,并且把你的ServiceConfig放在前面,保证它先被处理:@SpringBootTest(classes = {ServiceConfig.class, LibConfig.class}) @ActiveProfiles("integrationTest") @DirtiesContext class IntegrationTest { // ... }
内容来源于stack exchange




