You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何让@SpringBootTest环境下的@ConditionalOnMissingBean注解正常生效?

如何让@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

火山引擎 最新活动