1. 程式人生 > >Spring -- 依賴注入(控制反轉)

Spring -- 依賴注入(控制反轉)

依賴注入  

Spring框架的核心功能有兩個:

Spring容器作為超級大工廠,負責建立、管理所有的Java物件,這些Java物件被稱為Bean。

Spring容器管理容器中Bean之間的依賴關係,Spring使用一種被稱為"依賴注入"的方式來管理Bean之間的依賴關係。

使用依賴注入,不僅可以為Bean注入普通的屬性值,還可以注入其他Bean的引用。依賴注入是一種優秀的解耦方式,

其可以讓Bean以配置檔案組織在一起,而不是以硬編碼的方式耦合在一起。

理解依賴注入

IoC(控制反轉)和DI(依賴注入)的意思是相同的,只是表述方式不一樣。

當某個Java物件(呼叫者)需要呼叫另一個Java物件(被依賴物件)的方法時,傳統模式下通常有兩種做法:

1.原始做法:呼叫者主動建立被依賴物件,然後再呼叫被依賴物件的方法。

就比如A類中要使用B類的方法,必須要先建立B類例項,再由B類例項呼叫B類的方法

2.簡單工廠模式:呼叫者先找到被依賴物件的工廠,然後主動通過工廠去獲取被依賴物件,最後再

呼叫被依賴物件的方法:

Phone p = PhoneFactory.getPhone();

p.callSomeOne(String phoneNum);

兩種方式獲取被依賴物件的方式都是主動的,這必然會導致呼叫者與被依賴物件之間的硬編碼耦合,

非常不利於專案的升級和維護。使用Spring框架之後,呼叫者無需主動獲取被依賴物件,呼叫者只需要

被動的接受Spring容器為呼叫者建立的依賴物件即可。

核心配置檔案中的定義:

最後Java程式碼中就不需要主動去建立依賴物件了,這個依賴的過程由Spring實現:

由此可以見,使用了Spring後,呼叫者獲取被依賴物件的方式由原來的主動獲取,變成了被動接受 ,

所以Spring的創始人稱之為控制反轉。

但是從Spring的角度來看,Spring容器負責將被依賴的物件賦值給呼叫者的成員變數,相當於為呼叫者

注入它依賴的例項,另一個說法:依賴注入就是由此得來的。

實現依賴注入的方式

Spring支援3中依賴注入的方式,屬性注入、構造器注入、工廠方法注入(使用較少)

1.屬性注入

屬性注入是指IoC容器通過成員變數的setter方法來注入bean的屬性值或者被依賴物件。這種注入方式簡單、

直觀,因而再Spring的依賴注入裡大量使用。屬性注入使用<property>元素,使用name屬性指定bean的屬性

名稱,value屬性指定屬性值

2.構造器注入

利用構造器來設定依賴關係的方式,被稱為構造注入。通俗來說,就是驅動Spring在底層以反射方式

執行帶指定引數的構造器,當執行帶引數的構造器時,就可利用構造器引數對成員變數進行初始化:

bean類:

構造器注入的傳參方式有三種:

1.按照索引匹配入參:

索引從0開始,表示構造器引數列表中的順序,這種方式的缺點也很明顯:

引數列表的順序如果調整了,配置檔案也需要跟著調整。

2.按型別匹配入參:

type的值是型別的全路徑,這裡constructor標籤的順序也表示引數列表的順序,

如果構造器中列表是這樣的:(String name , String sex , int age),那麼為name

賦值的constructor標籤應該放在第一位,sex第二,age第三。

3.根據屬性名入參:

這種方式是最穩的了,不多BB。

自動裝配

Spring IOC 容器可以自動裝配 Bean,需要做的僅僅是在 <bean> 的 autowire 屬性裡指定自動裝配的模式,

它能夠將當前例項中所有的物件屬性全部進行填充。

byType是根據型別自動裝配,但要求是依賴Bean在容器中只能有一個例項。

若IoC容器中有多個與目標Bean型別一致的Bean,容器將無法判斷哪個Bean最適合該屬性,會報錯。

byName是根據名稱自動裝配,要求是依賴的Bean的名稱和屬性名設定的完全相同。

這個屬性名指的是Bean中定義的欄位名:

那麼在配置檔案中對應的依賴bean的id值,也得是a:

自動裝配的缺點:

1.在配置檔案裡設定autowire屬性進行自動裝配將會裝配Bean的所有屬性,如果只希望裝配個別屬性時,

autowire屬性就不夠靈活了。

2.autowire屬性要麼根據型別自動裝配,要麼根據名稱自動裝配,不能兩者兼有之。