Spring重写主bean与非主bean

我试图在使用@Primary在测试配置中声明的测试期间覆盖Spring bean . 一个声明位于src / main / java路径中,另一个声明位于src / test / java路径中 .

但是,Spring故意用非主bean替换主bean,这是我不想用于测试的bean . 如果我只是注释掉 生产环境 (src / main / java)配置bean,它会根据需要在测试配置中使用主测试(src / main / test)bean . (显然,每次我想运行测试时都无法注释掉代码 . )

从日志:

o.s.b.f.s.DefaultListableBeanFactory - 使用不同的定义覆盖bean'sqsConnectionFactory'的bean定义:replacement [Root bean:class [null];范围=;抽象= FALSE; lazyInit = FALSE; autowireMode = 3; dependencyCheck = 0; autowireCandidate = TRUE;初级= TRUE; factoryBeanName = testJmsConfiguration; factoryMethodName = sqsConnectionFactory; initMethodName = NULL; destroyMethodName =(推断);使用[Root bean:class [null];在类路径资源[com / foo / configuration / TestJmsConfiguration.class]]中定义范围=;抽象= FALSE; lazyInit = FALSE; autowireMode = 3; dependencyCheck = 0; autowireCandidate = TRUE;初级= FALSE; factoryBeanName = jmsConfiguration; factoryMethodName = sqsConnectionFactory; initMethodName = NULL; destroyMethodName =(推断);在类路径资源[com / foo / configuration / JmsConfiguration.class]中定义]

Why is spring replacing a primary bean with a non-primary bean and how do I get Spring to use the bean specifically marked as the primary 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"})

回答(2)

3 years ago

@Primary 仅在注入点生效,当存在冲突时,因为不同的bean匹配要注入的条件,并且需要做出决定 .

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

3 years ago

我想你可能在测试课中缺少 @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 {

}