天天看點

《Spring攻略(第2版)》——1.11 用XML配置自動裝配Bean

本節書摘來自異步社群《spring攻略(第2版)》一書中的第1章,第1.11節,作者: 【美】gary mak , josh long , daniel rubio著,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視

1.11.1 問題

當一個bean需要通路另一個bean時,你可以顯式指定引用裝配它。但是,如果你的容器能夠自動裝配bean,就可以免去手工配置裝配的麻煩。

1.11.2 解決方案

spring ioc容器能夠幫助你自動裝配bean。你隻要在的autowire屬性中指定自動裝配模式就可以了。表1-2列出了spring支援的自動裝配模式。

《Spring攻略(第2版)》——1.11 用XML配置自動裝配Bean

*預設模式是no,但是可以設定根元素的default-autowire屬性修改。這個預設模式将被bean自己指定的模式覆寫。

盡管自動裝配功能非常強大,但代價是降低了bean配置的可讀性。因為自動裝配由spring在運作時執行,你無法從bean配置檔案中得到bean裝配的方式。在實踐中,我們建議僅将自動裝配應用到元件依賴不複雜的應用程式中。

1.11.3 工作原理

按照類型的自動裝配

你可以将sequencegenerator bean的autowire屬性設定為bytype并且不設定prefixgenerator屬性。然後,spring将試圖裝配類型與prefixgenerator相容的bean。在這個例子中,将自動裝配dateprefixgenerator bean。

按照類型的自動裝配的主要問題是有時候在ioc類型中具有超過一個與目标類型相容的bean。在這種情況下,spring将無法确定哪個bean最适合于該屬性,進而無法進行自動裝配。例如,如果你有另一個以目前年份作為字首的字首生成器,按照類型的自動裝配将會立即被破壞。

如果找到超過一個可供自動裝配的bean,spring将會抛出一個unsatisfieddependency exception異常。

按照名稱的自動裝配

byname是另一種自動裝配模式,有時候它能解決按照類型的自動裝配的問題。它的工作方式與bytype類似,但是這時候,spring将試圖裝配一個類名與該屬性名相同的bean,而不是相容的類型。因為bean的name屬性在一個容器中是唯一的,按照名稱的自動裝配不會導緻歧義。

但是,按照名稱的自動裝配并不能工作于任何情況。有時候,你不可能使目标bean的名稱與屬性相同。在實踐中,你往往必須在保持其他依賴自動裝配的同時明确地指定歧義的依賴。這意味着你混合了顯式裝配和自動裝配。

按照構造程式的自動裝配

constructor自動裝配模式與bytype的工作方式類似,但是更複雜一些。對于具有單個構造程式的bean,spring将試圖為每個構造程式參數裝配一個具有相容類型的bean。但是對于具有多個構造程式的bean,這一過程就更加複雜。spring首先試圖為每個構造程式的每個參數找到一個類型相容的bean。然後,将選擇具有最多比對參數的構造程式。

假定sequencegenerator有一個預設構造程式和一個具有參數prefixgenerator的構造程式。

在這種情況下,第二個構造程式比對并且被選中,因為spring可以找到一個類型與prefix generator相容的bean。

但是,一個類中的多個構造程式可能造成構造程式參數比對的歧義。如果你要求spring确定一個構造程式,情況可能更加複雜。是以,如果你使用這種自動裝配模型,就要非常小心地避免歧義。

自動檢測的自動裝配

自動裝配模式autodetect要求spring在bytype和constructor模式中作出決定。如果至少找到一個沒有參數的預設構造程式,将選擇bytype模式,否則,将選擇constructor模式。因為sequencegenerator類定義了預設的構造程式,将選擇bytype模式。這意味着字首生成器将通過設值方法注入。

自動裝配與依賴檢查

你已經看到,如果spring找到超過一個候選的自動裝配bean,将會抛出unsatisfieddependency exception異常。另一方面,如果自動裝配模式設定為byname或bytype,而spring無法找到比對的bean進行裝配,将把該屬性保持為未設定狀态,這可能導緻一個nullpointerexception異常或者一個值沒有初始化。但是,如果你希望在自動裝配無法裝配的bean時得到通知,應該将dependency-check屬性設定為objects或者all。

在這種情況下,如果自動裝配無效将會抛出unsatisfieddependencyexception異常。objects将通知spring在相同的bean工廠中無法找到協同bean時發出一個錯誤。all通知容器在任何作為依賴的簡單屬性類型(string類型或者原始類型)未被設定時發出一個錯誤,這補充了objects的功能。