2012-11-02 61 views
10

我有一顆豆:爲什麼我需要自動佈線/注入字段的setter?

<bean id="BasketLogic" class="efco.logic.EfcoBasketLogic" autowire="byType"> 
     <property name="documentLogic" ref="DocumentLogic" /> 
     <property name="stateAccess" ref="StateAccess" /> 
     <property name="contextAccess" ref="ContextAccess" /> 
    </bean> 

    <bean id="EfcoErpService" autowire="byType" class="efco.erp.service.EfcoErpServiceImpl"> 
    <constructor-arg ref="ErpConnector"/> 
    </bean> 

documentLogicstateAccesscontextAccess是在BasketLogicImpl

和領域,我沒有<context:component-scan />

EfcoBasketLogic.java:

public class EfcoBasketLogic extends BasketLogicImpl { 

     @Inject 
     private EfcoErpService erpService; 
    ... 
    ... 
    ... 
} 

erpService是null,除非我提供setter。但爲什麼?我認爲在自動裝配發生的地方不需要安裝人員? BasketLogicImpl會對此負責嗎?

回答

11

您需要使用setter,因爲除非通過<context:component-scan /><context:annotation-config />來通知彈簧,否則不會檢測註釋。由於您指定了autowire="byType",因此檢測到Setter。

你會發現這個問題,答案有幫助,以及:When to use autowiring in Spring

+0

如果我這樣做會出現一個新問題 - > _沒有定義類型爲[xyz]的唯一bean:期望的單個匹配bean,但找到5_。這是由其他bean引起的,我通過''顯式注入了一個屬性,並且有5個bean實現了該接口。屬性'x'有註解@Inject。所以看起來顯式定義不會覆蓋自動裝配的東西? – GarfieldKlon

+0

如果只有一個給定類型的bean或一個標記爲primary的bean,那麼'@ Inject'將被正確解析。如果你有多種這種類型的可互換bean,你需要使用'@ Resource'或xml按名稱注入。 – mrembisz

+0

即使我通過''顯式注入這個bean? – GarfieldKlon

1

首先,使用<context:component-scan /><context:annotation-config />使春天來掃描你的代碼爲符合條件的豆類,以滿足依賴關係,這將大大提高它的能力正確連線它們,所以我建議將它們添加到您的上下文文件中。

其次,您應該知道@Inject是一個標準(意思是JSR-330規範)註釋。將Spring註釋與標準註釋混合搭配是可以的,但這樣做時行爲可能會有所不同。 @Named通常與@Inject配對以匹配具有依賴關係的組件(兩個JSR-330)。有關詳細信息,請參閱此reference,並參閱表4.6以獲取使用註釋。

但是要直接回答你的問題,「爲什麼我需要一個setter當不使用組件掃描」,是,因爲你沒有使用組件掃描。你要求Spring注入一個依賴「byType」,但不允許Spring爲你的代碼掃描那些類型的組件。 setter工作的原因是被注入的setter參數的類型可以被Spring在編譯的字節碼(即元數據)中發現,所以它成功地解決了你的請求。

+0

僅供參考:使用''時,確保在聲明bean類的類層次結構的根目錄中設置base-package屬性(通過@Named或@Autowired)。例如: pmhargis

0

我的理解是XML配置會覆蓋註釋配置。autowire =「byType」指定的事實會覆蓋自動注入,它會查找注入依賴項的setter方法。

相關問題