2013-10-16 78 views
1

通過擴展原始@Configuration類來覆蓋Javaconfig Bean時,我想爲新的Bean定義添加@DependsOn。Javaconfig bean overiding沒有考慮添加@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

經過一段時間沒有評論,我會解決jira問題,看看是否真的是一個錯誤。 –

+0

嗨,何塞,我創建了https://jira.springsource.org/browse/SPR-10992,但還沒有答案 – bla

回答

0

正如何塞·路易斯·馬丁指出,已經添加檢查,這已被證實是由Spring團隊的錯誤。

我和workarounded它:

@DependsOn("doInit") 
@Bean 
public Void notOverridingBean() { 
    return null; 
} 

@Bean 
public Object bean(Object notOverridingBean) { 
    return "overriden"; 
} 

的替代方法是覆蓋另一個@Configuration類的豆。

1

對我來說似乎是一個錯誤。

當在配置類中覆蓋@Bean工廠方法時,父代BeanDefinition獲勝並在覆蓋子代BeanFactory上註冊。

所以你不能用註釋來配置bean(因爲它會被覆蓋)。

下面的測試結果預計:< [doInit]>卻被:< [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

這可能是固定的,如果beanMethod是從超在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); 
}