通过扩展原始的@Configuration类来覆盖Javaconfig Bean,我想为新的Bean定义添加一个@DependsOn。
但是,这种依赖似乎不会被考虑在内。这是一个TestCase再现我的问题:
public class SpringTest {
@Test
public void testDependsOnTakenInAccount() {
AnnotationConfigApplicationContext ctx2 = new AnnotationConfigApplicationContext(AConfig.class, CConfig.class);
Assert.assertEquals("overriden", ctx2.getBean("bean"));
}
@Configuration
public static class AConfig {
@Bean
public Object bean() {
return "not overriden";
}
}
@Configuration
public static class CConfig extends AConfig {
protected boolean isInitialized = false;
@Bean
public Void doInit() {
isInitialized = true;
return null;
}
@Bean
@DependsOn("doInit")
public Object bean() {
if (!isInitialized) {
throw new RuntimeException("Not initialized");
}
return "overriden";
}
}
}
这是预期的行为吗?如果是,我如何在覆盖bean时添加依赖项?
答案 0 :(得分:1)
对我来说似乎是一个错误。
在配置类中覆盖@Bean
工厂方法时,父BeanDefinition
获胜并在BeanFactory
上注册,覆盖孩子。
因此,您无法使用注释配置bean(因为它将被覆盖)。
以下测试结果
预期:其中[doInit] GT;但是:< [otherBean]>
@RunWith(JUnit4ClassRunner.class)
public class DependOnTest {
@Test
public void testBeanDefinitionOverriding() {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Config.class);
BeanDefinition bd = ctx.getBeanDefinition("bean");
Assert.assertEquals("doInit", bd.getDependsOn()[0]);
}
@Configuration
public static class ParentConfig {
@Bean
@DependsOn("otherBean")
public String bean() {
return "not overriden";
}
@Bean
public String otherBean() {
return "otherBean";
}
}
@Configuration
public static class Config extends ParentConfig {
@Bean
public String doInit() {
return "doInit";
}
@Bean
@DependsOn("doInit")
public String bean() {
return "overriding";
}
}
}
我认为问题始于ConfigurationClassParser:
// recursively process the configuration class and its superclass hierarchy
do {
metadata = doProcessConfigurationClass(configClass, metadata);
}
while (metadata != null);
将覆盖方法的结果添加到CongurationClass.beanMethods
可以修复是否已经从ConfigurationClass.addBeanMethod()
public void addBeanMethod(BeanMethod method) {
// Check if already added a bean method from superclass
for (BeanMethod beanMethod : beanMethods) {
if (beanMethod.getMetadata().getMethodName().equals(method.getMetadata().getMethodName()) &&
!(beanMethod.getMetadata().getDeclaringClassName()).equals(method.getMetadata().getDeclaringClassName()))
// log and return.
return;
}
this.beanMethods.add(method);
}
答案 1 :(得分:0)
正如何塞·路易斯·马丁所指出的,这已被Spring团队确认为一个错误。
我的工作方式是:
@DependsOn("doInit")
@Bean
public Void notOverridingBean() {
return null;
}
@Bean
public Object bean(Object notOverridingBean) {
return "overriden";
}
另一种方法是在另一个@Configuration类中覆盖bean。