我试图在使用@Primary在测试配置中声明的测试期间覆盖Spring bean。一个声明在src / main / java路径中,另一个声明在src / test / java路径中。
但是,Spring故意用非主要bean替换主bean,我不想用于测试。如果我只是注释掉生产(src / main / java)配置bean,它会根据需要在测试配置中使用主测试(src / main / test)bean。 (显然,每次我想进行测试时,我都无法注释掉代码。)
来自日志:
o.s.b.f.s.DefaultListableBeanFactory - 覆盖bean' sqsConnectionFactory'的bean定义使用不同的定义:替换 [Root bean:class [null];范围=;抽象= FALSE; lazyInit = FALSE; autowireMode = 3; dependencyCheck = 0; autowireCandidate = TRUE; primary = true; factoryBeanName = testJmsConfiguration; factoryMethodName = sqsConnectionFactory; initMethodName = NULL; destroyMethodName =(推断);在类路径资源[com / foo / configuration / TestJmsConfiguration.class]]
中定义带
[root bean:class [null];范围=;抽象= FALSE; lazyInit = FALSE; autowireMode = 3; dependencyCheck = 0; autowireCandidate = TRUE;的初级=假; factoryBeanName = jmsConfiguration; factoryMethodName = sqsConnectionFactory; initMethodName = NULL; destroyMethodName =(推断);在类路径资源[com / foo / configuration / JmsConfiguration.class]]
中定义
为什么spring用非主bean替换主bean?如何让Spring使用专门标记为主bean的bean?
编辑: 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"})
答案 0 :(得分:9)
@Primary
仅在注入点生效,当存在冲突时,因为不同的bean匹配要注入的条件,并且需要做出决定。
@Primary
。当您使用两种不同的方法创建相同的bean时,并且您没有命名它们中的任何一个Spring认为您正在尝试覆盖它,因此可能会发生此行为。鉴于名称是最简单的解决方案,但请记住,您的上下文仍将初始化您不想使用的bean。
答案 1 :(得分: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 {
}