自動裝配協作者

Spring 容器可以自動裝配協作 Bean 之間的關係。您可以讓 Spring 通過檢查 ApplicationContext 的內容,自動為您的 Bean 解析協作者(其他 Bean)。自動裝配具有以下優點

  • 自動裝配可以顯著減少指定屬性或建構子引數的需求。(其他機制,例如本章其他地方討論的 Bean 範本,在這方面也很有價值。)

  • 自動裝配可以在物件演進時更新配置。例如,如果您需要向類別新增依賴項,則可以自動滿足該依賴項,而無需修改配置。因此,自動裝配在開發期間可能特別有用,而不會否定在程式碼庫變得更穩定時切換到顯式裝配的選項。

當使用基於 XML 的配置元資料時(請參閱依賴注入),您可以使用 <bean/> 元素的 autowire 屬性為 Bean 定義指定自動裝配模式。自動裝配功能有四種模式。您可以為每個 Bean 指定自動裝配,因此可以選擇要自動裝配的 Bean。下表描述了四種自動裝配模式

表 1. 自動裝配模式
模式 說明

no

(預設)不自動裝配。Bean 參考必須由 ref 元素定義。不建議在較大型部署中變更預設設定,因為顯式指定協作者可以提供更大的控制和清晰度。在某種程度上,它記錄了系統的結構。

byName

依屬性名稱自動裝配。Spring 尋找與需要自動裝配的屬性名稱相同的 Bean。例如,如果 Bean 定義設定為依名稱自動裝配,並且它包含 master 屬性(也就是說,它具有 setMaster(..) 方法),則 Spring 會尋找名為 master 的 Bean 定義,並使用它來設定屬性。

byType

如果容器中存在屬性類型的 Bean 恰好只有一個,則允許自動裝配屬性。如果存在多個,則會擲回嚴重例外狀況,這表示您可能無法為該 Bean 使用 byType 自動裝配。如果沒有相符的 Bean,則不會發生任何事(不會設定屬性)。

constructor

類似於 byType,但適用於建構子引數。如果容器中不存在建構子引數類型的 Bean 恰好只有一個,則會引發嚴重錯誤。

使用 byTypeconstructor 自動裝配模式,您可以裝配陣列和類型化集合。在這種情況下,容器中與預期類型相符的所有自動裝配候選項目都會提供以滿足依賴項。如果預期的金鑰類型為 String,則可以自動裝配強類型 Map 實例。自動裝配的 Map 實例的值包含與預期類型相符的所有 Bean 實例,而 Map 實例的金鑰包含對應的 Bean 名稱。

自動裝配的限制和缺點

當在整個專案中一致地使用自動裝配時,自動裝配效果最佳。如果一般不使用自動裝配,則開發人員可能會感到困惑,只使用它來裝配一兩個 Bean 定義。

考慮自動裝配的限制和缺點

  • propertyconstructor-arg 設定中的顯式依賴項始終會覆寫自動裝配。您無法自動裝配簡單屬性,例如基本類型、StringsClasses(以及此類簡單屬性的陣列)。此限制是設計使然。

  • 自動裝配不如顯式裝配精確。雖然如先前表格中所述,Spring 會小心避免在可能產生意外結果的歧義情況下進行猜測。Spring 管理的物件之間的關係不再顯式記錄。

  • 裝配資訊可能無法提供給可能從 Spring 容器產生文件化的工具。

  • 容器內的多個 Bean 定義可能與 setter 方法或建構子引數指定的要自動裝配的類型相符。對於陣列、集合或 Map 實例,這不一定是問題。但是,對於期望單一值的依賴項,此歧義不會任意解決。如果沒有可用的唯一 Bean 定義,則會擲回例外狀況。

在後一種情況下,您有幾種選項

  • 放棄自動裝配,改用顯式裝配。

  • 通過將 Bean 定義的 autowire-candidate 屬性設定為 false 來避免自動裝配,如下一節所述。

  • 通過將 <bean/> 元素的 primary 屬性設定為 true,將單一 Bean 定義指定為主要候選項目。

  • 實作基於註解的配置提供的更精細控制,如基於註解的容器配置中所述。

從自動裝配中排除 Bean

在每個 Bean 的基礎上,您可以從自動裝配中排除 Bean。在 Spring 的 XML 格式中,將 <bean/> 元素的 autowire-candidate 屬性設定為 false;使用 @Bean 註解時,該屬性名為 autowireCandidate。容器使該特定 Bean 定義無法用於自動裝配基礎架構,包括基於註解的注入點,例如 @Autowired

autowire-candidate 屬性旨在僅影響基於類型的自動裝配。它不會影響依名稱的顯式參考,即使指定的 Bean 未標記為自動裝配候選項目,這些參考也會解析。因此,如果名稱相符,依名稱自動裝配仍會注入 Bean。

您還可以根據 Bean 名稱的模式比對來限制自動裝配候選項目。最上層的 <beans/> 元素在其 default-autowire-candidates 屬性中接受一個或多個模式。例如,要將自動裝配候選項目狀態限制為名稱以 Repository 結尾的任何 Bean,請提供值 *Repository。要提供多個模式,請在逗號分隔的列表中定義它們。Bean 定義的 autowire-candidate 屬性的顯式值 truefalse 始終優先。對於此類 Bean,模式比對規則不適用。

這些技術對於您永遠不希望通過自動裝配將 Bean 注入到其他 Bean 中的情況非常有用。這並不表示排除的 Bean 本身無法通過使用自動裝配來配置。相反,該 Bean 本身不是自動裝配其他 Bean 的候選項目。

從 6.2 開始,@Bean 方法支援自動裝配候選標誌的兩種變體:autowireCandidatedefaultCandidate

當使用限定符時,標記為 defaultCandidate=false 的 Bean 僅適用於存在其他限定符指示的注入點。這對於限制性委派很有用,這些委派應該在某些區域中可注入,但不應妨礙其他位置中相同類型的 Bean。此類 Bean 永遠不會僅通過純宣告類型注入,而是通過類型加上特定限定符注入。

相反,autowireCandidate=false 的行為與上面說明的 autowire-candidate 屬性完全相同:此類 Bean 永遠不會通過類型注入。