我正在尝试使用@Primary在测试配置中声明的测试中覆盖Spring bean。一个声明位于src / main / java路径中,另一个声明主要位于src / test / java路径中。
但是,Spring故意将非主要bean替换为主要bean,我不想在测试中使用该bean。如果仅将生产(src / main / java)配置bean注释掉,它会根据需要在测试配置中使用主测试(src / main / test)bean。(显然,每次运行测试时,我都无法注释掉代码。)
从日志中:
osbfsDefaultListableBeanFactory- 用不同的定义覆盖bean’sqsConnectionFactory’的bean定义:替换 [Root bean:class [null]; scope =; abstract = 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]; scope =; abstract = false; lazyInit = false; autowireMode = 3; dependencyCheck = 0; autowireCandidate = true; primary = false ; factoryBeanName = jmsConfiguration; factoryMethodName = sqsConnectionFactory; initMethodName = null; destroyMethodName =(推断); 在类路径资源[com / foo / configuration / JmsConfiguration.class]中定义
osbfsDefaultListableBeanFactory- 用不同的定义覆盖bean’sqsConnectionFactory’的bean定义:替换 [Root bean:class [null]; scope =; abstract = 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]; scope =; abstract = false; lazyInit = false; autowireMode = 3; dependencyCheck = 0; autowireCandidate = true; primary = false ; 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"})
@Primary 当由于不同的bean匹配要注入的条件而发生冲突时,仅在注入点才有效,并且需要做出决定。
@Primary
@Primary在bean初始化时不使用。当您使用两种不同的方法创建同一个bean时,您没有命名它们中的任何一个,Spring认为您试图覆盖它,因此可能会发生这种情况。给定名称是最简单的解决方案,但请记住,上下文仍将初始化您不想使用的bean。