用非主豆覆盖主豆的弹簧

我正在尝试在测试配置中声明的测试期间使用@Primary覆盖Spring Bean。一个声明位于 src/main/java 路径中,另一个(主声明)位于 src/test/java 路径中。

但是,Spring故意用非主豆代替主豆,我不想在测试中使用。如果我只是简单地注释掉了生产(src/main/java)配置bean,它会根据需要在测试配置中使用主测试(src/main/test)bean。(显然,每次我想运行测试时,我都不能注释掉代码。

从日志中:

o.s.b.f.s.DefaultListableBeanFactory - 用不同的定义替换bean 'sqsConnectionFactory'的bean定义:替换[Root bean:class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true;主 = 真;factoryBeanName=testJmsConfiguration;factoryMethodName=sqsConnectionFactory;initMethodName=null;destroyMethodName=(推断);在类路径资源中定义 [com/foo/configuration/TestJmsConfiguration.class]]

[Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true;主要 = 假;factoryBeanName=jmsConfiguration;factoryMethodName=sqsConnectionFactory;initMethodName=null;destroyMethodName=(推断);在类路径资源中定义 [com/foo/configuration/JmsConfiguration.class]]

为什么Spring用非主豆代替主豆,我如何让Spring使用专门标记为主豆的豆子?

编辑:src/main/java 配置:

@Configuration
public class JmsConfiguration {

... other bean declarations here ...

@Bean
public SQSConnectionFactory sqsConnectionFactory(Region region) throws JMSException {
    return SQSConnectionFactory.builder()
            .withRegion(region)
            .build();
}
}

测试配置:

@Configuration
public class TestJmsConfiguration {

@Bean(name="messageProducerMock")
public MessageProducer mockMessageProducer() {
    return new MessageProducerMock();
}

... other bean declarations here ...

@Bean
@Primary
public SQSConnectionFactory sqsConnectionFactory(@Qualifier("messageProducerMock") MessageProducer messageProducerMock) throws JMSException {
    ... returning setup mock here
}
}

带有测试的类用以下方式进行注释:

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles(profiles = {"test"})

答案 1

@Primary只有在注射点生效,因为不同的豆子与要注射的条件匹配而发生冲突时,需要做出决定。

@Primary在豆类初始化时不使用。由于您正在使用两种不同的方法来创建相同的bean,并且您没有命名Spring认为您正在尝试覆盖它的任何一个,因此会发生这种行为。给定一个名称是最简单的解决方案,但请记住,您的上下文仍将初始化您不想使用的bean。


答案 2

我认为你可能在你的测试课上失踪了。@ContextConfiguration

测试配置类示例(src/test/java/TestConfiguration.class):

@Configuration
@ComponentScan
public class TestConfiguration {
    @Bean
    RabbitSender rabbitSender() {
        return mock(RabbitSender.class);
    }

}

测试类示例:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfiguration.class)
public class SomeServiceTest {

}

推荐