2013-03-13 59 views
4

我很難理解爲什麼使用@Autowired的Spring Java Config中的某些內容不起作用。使用Autowired導致的NPE的Spring Java Config

首先,我試圖在Java配置類中移動我所有的@Autowired註釋。這會使我的「POJO」變成真正的POJO。那麼我不僅可以在Spring上下文之外輕鬆測試它們,還可以輕鬆方便地使用模擬對象。

所以我第一次嘗試這樣的:

@Configuration 
public class Module3ConfigClass { 

    @Autowired 
    private Module1Bean1 module1Bean1; 

    @Autowired 
    private Module2Bean1 module2Bean1; 

    @Bean 
    public Module3Bean1 module3Bean1() { 
     return new Module3Bean1(module1Bean1, module2Bean1); 
    } 
} 

然而,在調用Module3Bean1構造時,無論是在豆類傳遞爲空。如果你沒有遵循我上面的命名規則,那麼這兩個bean將由一個單獨的Java Config配置文件創建。另外請注意,所有內容都是正確連線 - 我知道這一點,因爲當@Autowired標籤位於Module3Bean1內的相應私人成員字段中時,一切正常。

FWIW,我試着給module3Bean1()方法添加一個@DependsOn註解,但是結果相同。我想我真的很想理解這種行爲,這是否正確(我懷疑是這樣,但爲什麼)?

最後,我發現這裏顯示一個可接受的解決方法:

@Configuration 
public class Module3ConfigClass { 

    @Bean 
    @Autowired 
    public Module3Bean1 module3Bean1(Module1Bean1 module1Bean1, Module2Bean1 module2Bean1) { 
     return new Module3Bean1(module1Bean1, module2Bean1); 
    } 
} 

這似乎沒什麼問題,但如果有人會照顧對此發表評論,這將是受歡迎的爲好。

+3

豆類在自動裝配之前需要被創建。向我們展示這些bean在哪裏,另一個配置。你可能需要'@ Import'這個'@ Configuration'類。 – 2013-03-13 17:31:14

+1

在上述兩種情況下,它們都是自動裝配的。首先是當自動裝配不在工廠(配置)過程中時,而第二個是在顯示的代碼中自動裝配的時候。所以假設這些都是簡單的bean,每個都在它們自己的(at)配置註釋類中並正確導入。我只是想知道爲什麼一些(在)Autowired bean出現在(at)配置類中,而有些(如上所示)則不會。 – JoeG 2013-03-13 17:41:48

+0

然後我只能假設所有的bean都是在注入/自動裝配之前創建的。至於你的解決方法,我認爲這個方法可能會被調用兩次,一次用於@ Bean創建,一次用於'@ Autowired'。檢查你的日誌。 – 2013-03-13 17:45:26

回答

1

我想你遇到了我剛纔遇到的同樣的問題。在我的情況下,問題是無效的XML配置。在我的模塊B我喜歡的配置:

<beans> 
     <context:component-scan base-package="com.moduleB"/> 
     <import resource="classpath:applicationContext-moduleA.xml"/> 
</beans> 

在moduleA情況下,我把「背景:註解配置」的註釋。 當我改變進口/上下文以:

<beans> 
     <import resource="classpath:applicationContext-moduleA.xml"/> 
     <context:component-scan base-package="com.moduleB"/> 
</beans> 

自動裝配配置類的屬性開始工作。

+0

對不起,我錯過了這個回覆的時候!這對其他人來說是很好的信息,但是因爲我沒有XML配置,並且是純Java配置,所以這並不能回答這個問題(只是告訴你爲什麼我不能接受這個問題作爲答案!) – JoeG 2013-10-17 11:05:30

0

我們有同樣的問題,並得出結論,錯誤產生,因爲我們有一個循環依賴關係,其中涉及BeanPostProcessor

  • 提供一個PropertyPlaceholderConfigurer(了BeanPostProcessor)已被配置爲設置其propertiesArray屬性與另一豆的幫助下:

    <bean id="globalPropertyPlaceholderConfigurer" 
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" 
        lazy-init="false" depends-on="javaLoggingConfigurer"> 
        <property name="locations"> 
         <list> 
          <value>classpath:config/host/${env.instance}.properties</value> 
          <value>WEB-INF/config/host/${env.instance}.properties</value> 
         </list> 
        </property> 
        <property name="ignoreResourceNotFound" value="true" /> 
        <property name="propertiesArray" value="#{springPropertyFinder.findProperties()}" /> 
    </bean> 
    
  • 用過springPropertyFinder豆設置propertiesArray是了BeanPostProcessor而是收集所有屬性實例的「普通」bean:

    public Properties[] findProperties() { 
        Map<String, Properties> propertiesMap = applicationContext.getBeansOfType(Properties.class); 
    
        for (String title : propertiesMap.keySet()) { 
         PropertiesLoggerUtil.logPropertiesContent(logger, "Springcontext Properties ("+title+")", propertiesMap.get(title)); 
        } 
    
        return propertiesMap.values().toArray(new Properties[propertiesMap.size()]); 
    } 
    
  • 個的@Configuration類包含類型屬性的豆

因此,我們的假設是,@Configuration類已不被ConfigurationClassPostProcessor(還了BeanPostProcessor)正在處理中產生的,因爲PropertyPlaceholderConfigurer依賴於springPropertyFinder,這取決於@Configuration類中的屬性bean。在這些情況下,BeanPostProcessors的順序可能沒有設置正確。

這個描述的設置工作在XML中,但不是用Java配置。

+1

這看起來很相似 - @Autowired也是一個後處理步驟。在本文後的幾個月裏,我們也能夠確認(或者我們認爲是)這是一個循環參考問題。我懷疑(儘管沒有任何證據),自從Autowired被很久以前支持(2.5我認爲)Java Config(3.x)出現的時候,嵌套的配置類中就隱藏着一個微妙的問題。 – JoeG 2013-11-20 14:45:29