深入理解Spring4框架(四) 依賴

2021-07-15 12:44:35 字數 3521 閱讀 3158



乙個典型的企業應用不止包含乙個物件,即使是乙個簡單的應用,也是由幾個物件合作來完成使用者需要使用的功能。本節將介紹定義的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.建立乙個介...