乙個典型的企業應用不止包含乙個物件,即使是乙個簡單的應用,也是由幾個物件合作來完成使用者需要使用的功能。本節將介紹定義的bean是如何在真實系統中配合來完成既定功能的。
依賴注入就是在物件構建完成後,為其定義依賴的過程。容器會在建立bean的時候將這些依賴注入進去。這個過程跟我們通常編碼不同,平常我們都需要在**中去new乙個物件,而這裡把這個操作交給容器了,由bean自己來控制依賴的例項化,與通常的方法是相反的,稱之為控制反轉(ioc)。
使用依賴注入的話,**會變得更加清晰,也將物件和依賴進行了解耦。
1 基於構造器的依賴注入
基於構造器的依賴注入是由容器來呼叫乙個帶有多個引數的構造器,和呼叫靜態工廠方法來構建bean類似。下面的例子表示乙個僅通過構造器進行依賴注入的類。
public class ******movielister
}
2 構造器引數解析
構造器使用引數型別來進行引數匹配。如果沒有引數衝突,那麼在bean定義中的引數順序即可確定乙個構造器。看下面乙個例子:
public class foo
}
沒有衝突的引數,假設bar和baz沒有繼承關係。因此下面的配置可以正常執行,而不需要在中指定index或type。
當另乙個bean被引用時,且型別是已知的,也會發生匹配。當乙個簡單型別被使用時,比如true,若不顯示地為其指定型別,那麼spring是不能確定這個value是什麼型別的。
public class examplebean
}
在之前的情況中,容器可以通過指定的type屬性來使用型別匹配,例如:
使用index屬性來顯示指定構造器引數的順序:
當遇到多個簡單型別的引數時,可以為其指定index來解決衝突。
也可以使用構造器引數名字來區分:
3 基於setter的依賴注入基於setter的依賴注入,是在bean完成例項化之後,容器呼叫bean的setter方法來完成的。
下面的類表明乙個類只能使用純粹的setter來注入依賴:
public class ******movielister
}
通常,我們使用基於構造器的注入來注入一些必選的依賴,而使用基於setter的注入來注入一些可選的依賴。
4 依賴解析過程
容器會如下所示執行依賴解析:
(2)當bean被建立時,它的依賴就會被注入。
(3)每個屬性或構造器引數實際上就是乙個待設定的值,或者是容器中另乙個bean的引用。
(4)每個屬性或構造器引數會被轉換為實際的型別。預設情況下,spring可以將string型別的值轉換為int, long, boolean等基本型別。
spring在容器建立時,會驗證每個bean的配置。然而,bean屬性是不會被設定的,直到bean實際上已被建立。那些是單例作用域和被設定為預例項化(預設)的bean,將會在容器建立時被同時建立。否則,bean會在需要的時候才會被建立。乙個bean的建立潛在地導致了一系列bean的建立。
如果兩個bean相互依賴,且均採用基於構造器的注入時,會報beancurrentlyincreationexception異常。可以將其改為基於setter的注入就可以解決這種迴圈依賴的問題。
5 使用depends-on
當乙個bean需要在其依賴的所有bean都初始化結束之後才能執行初始化,那麼就可以使用depends-on屬性來指定依賴。
6 懶載入bean
在xml中,懶載入通過lazy-init屬性來控制的。
7 自動注入
spring容器可以為bean自動注入依賴。
(1)自動注入可以極大減少對屬性或構造器引數的需要。
(2)自動注入不需要在依賴改變時修改配置檔案。
當使用基於xml的配置元資料時,可以使用autowire屬性來指定乙個bean的自動注入模式。自動注入功能由四種模式:
(1)no:這是預設的,不會自動注入。在大型部署中不建議修改預設配置,因為顯示地指定依賴會更加清晰和便於控制。
(2)byname:通過屬性名稱來自動注入。spring會查詢和屬性名稱相同的bean來自動注入。
(3)bytype:如果恰好有乙個bean與指定的型別相同,那麼自動注入這個bean。如果這個型別的bean超過乙個,會丟擲錯誤異常,也就意味著不能使用bytype來自動注入。
(4)constructor:跟bytype類似,但是適用於構造器引數。如果容器中不存在指定構造器引數型別的bean,或者多餘乙個的,那麼會丟擲錯誤異常。
自動注入的限制和缺點
當在乙個工程中均採用自動注入時,自動注入會表現得很好。若不是經常使用,而只用自動注入來注入乙個或兩個bean,那麼這樣會使得開發者感覺疑惑。
考慮以下限制和缺點:
(1)在property和constructor-arg設定的顯示依賴總是會覆蓋自動注入。
(2)自動注入沒有顯示指定那麼準確。也許,你不太容易找到bean所依賴的真正實現bean。
(3)不太容易通過工具來生成文件。
(4)指定型別也許會匹配到多個bean。
在spring的xml配置檔案中,將元素的autowire-candidate屬性設定為false,容器將不會自動注入這個bean。
8 方法注入
在很多應用場景中,大多數bean都是單例的。當乙個單例bean依賴另乙個單例bean;或者當乙個非單例bean需要依賴另乙個非單例bean,只需要將其中乙個bean定義為另乙個bean的屬性。當bean的生命週期不同時,問題就來了。假如單例bean a需要使用乙個非單例bean b,容器只會建立單例bean a一次,僅有一次機會來設定屬性。容器不能在每次呼叫bean a時提供乙個新的bean b例項。
public object process(map commandstate)
protected command createcommand()
}} 還可以換一種寫法,如下:
public abstract class commandmanager
protected abstract command createcommand();
}
上面的寫法簡潔了很多,但是createcommand()是乙個抽象方法,具體的實現類去哪兒了?
這裡,標籤用於指定createcommand()的實現類,這樣,commandmanager就解耦了spring框架**和業務**。spring框架使用cglib庫來動態生成commandmanager的子類,這個子類覆蓋了createcommand()這個抽象方法。
Spring基礎框架三 深入理解SpringMVC
spring mvc屬於springframework的後續產品,spring mvc框架提供了構建web應用程式的全功能mvc模組,是一種輕量級web框架。使用了mvc架構模式的思想,通過把model,view,controller分離,將web層進行職責解耦,把複雜的web應用分成邏輯清晰的幾部...
深入理解spring事務
事務介紹 乙個事務要麼同時成功,要麼同時失敗 特性事務隔離級別 傳播行為 唯讀事務只進行讀取操作 readonly true 告訴spring當前事務只會進行讀取操作,不會進行修改操作,可以幫助資料庫引擎優化 注 如果設定為唯讀的話,千萬不要在事務裡修改資料,使用唯讀操作時,spring不會進行加鎖...
深入理解Spring框架中的 依賴注入
spring framework spring框架的核心概念就是 依賴注入 什麼是依賴注入?其實理解起來很簡單,依賴注入其實就是框架用於連線各個應用程式的一項技術。框架負責將你的應用程式中的各種相互依賴進行連線起來,並從應用程式 中完全解決掉連線邏輯和物件建立。舉乙個描述收銀機的例子 1.建立乙個介...