我知道从已经讨论的@Configuration
中调用@Bean
注释方法。
,但我不明白为什么当豆被覆盖时它不起作用。
我有一个传统课,我无法修改。这是一种配置和商务豆。这是一个简化的版本:
@Configuration
public class MyBean {
String someMethod() {
return otherBean() + "|" + otherBean();
}
int called = 0;
@Bean
Object otherBean() {
return called ++;
}
}
在someMethod()
内部,工厂方法otherBean()
被称为两次,并且在用@Bean
注释的情况下,该实例应从弹簧上下文中获取,因此仅称为实际代码return called ++;
。someMethod()
的预期输出应始终是0|0
,并且在生产中确实如此。
当我要在单位测试中重新定义豆子时,麻烦就会出现:
@SpringJUnitConfig//(MyBean.class)
public class BeanTest {
@Autowired
MyBean myBean;
@Test
void testIt() {
assertEquals("0|0", myBean.someMethod());
}
@Configuration
static class TestConfig {
@Bean
MyBean myBean() {
return new MyBean();
}
}
}
原因可能是测试中MyBean
实例的一些其他设置(上面的摘要中未包含(。
现在,调用myBean.someMethod()
返回0|1
而不是0|0
。
一切再次起作用(结果是0|0
(,当删除TestConfig
配置并将测试上下文的配置设置为@SpringJUnitConfig(MyBean.class)
。
在测试中注册Bean有什么不同?
代理方法的"魔术"调用用@Bean
注释并从弹簧上下文返回实例仅在配置bean中发生(例如:@SpringJUnitConfig(MyBean.class)
(。
但是,当您创建一个新实例为return new MyBean()
时,@Configuration
的注释将被忽略,并且对象被注册为普通BEAN(@Bean MyBean myBean()
(,而不是配置。这就是为什么这些方法调用otherBean()
始终创建新实例的原因。