首页 文章

Spring boot 2.1 bean override与Primary

提问于
浏览
4

默认情况下使用Spring Boot 2.1 bean overriding is disabled,这是一件好事 .

但是我确实有一些测试,我使用Mockito用模拟实例替换bean . 使用默认设置,由于bean覆盖,具有此类配置的测试将失败 .

我发现工作的唯一方法是通过应用程序属性启用bean覆盖:

spring.main.allow-bean-definition-overriding=true

但是我真的希望确保我的测试配置的最小bean定义设置,这将由spring指出,覆盖禁用 .

我压倒的 beans 子要么是

  • 在导入到我的测试配置中的另一个配置中定义

  • 通过注释扫描自动发现bean

我在想的应该在测试配置中覆盖bean并在其上打一个 @Primary ,就像我们习惯于数据源配置一样 . 然而,这没有任何影响,让我想知道: @Primary 和残疾 beans 是否超越矛盾?

一些例子:

package com.stackoverflow.foo;
@Service
public class AService {
}

package com.stackoverflow.foo;
public class BService {
}

package com.stackoverflow.foo;
@Configuration
public BaseConfiguration {
    @Bean
    @Lazy
    public BService bService() {
        return new BService();
    }
}

package com.stackoverflow.bar;
@Configuration
@Import({BaseConfiguration.class})
public class TestConfiguration {
    @Bean
    public BService bService() {
        return Mockito.mock(BService.class);
    }
}

2 回答

  • 0

    覆盖bean意味着在上下文中可能只有一个具有唯一名称或id的bean . 所以你可以这样提供两个bean:

    package com.stackoverflow.foo;
    @Configuration
    public BaseConfiguration {
       @Bean
       @Lazy
       public BService bService1() {
           return new BService();
       }
    }
    
    package com.stackoverflow.bar;
    @Configuration
    @Import({BaseConfiguration.class})
    public class TestConfiguration {
        @Bean
        public BService bService2() {
            return Mockito.mock(BService.class);
        }
    }
    

    如果添加 @Primary ,那么将通过deafult注入主bean:

    @Autowired
    BService bService;
    
  • 1

    默认情况下允许使用@Bean覆盖@Component . 在你的情况下

    @Service
    public class AService {
    }
    
    @Component
    public class BService {
        @Autowired
        public BService() { ... }
    }
    
    @Configuration
    @ComponentScan
    public BaseConfiguration {
    }
    
    @Configuration
    // WARNING! Doesn't work with @SpringBootTest annotation
    @Import({BaseConfiguration.class})
    public class TestConfiguration {
        @Bean // you allowed to override @Component with @Bean.
        public BService bService() {
            return Mockito.mock(BService.class);
        }
    }
    

相关问题