Spring學習 -----IoC和DI概述

在實際的開發中,我們反覆儘量避免儘量降低對象間的依賴關係即耦合度。但是如何才能作到呢? 通常的業務對象之間都是依賴關係的,業務對象與業務對象,業務對象與持久層,業務對象與各種資源之間都存在這樣和那樣的依賴關係。



IoC (Inversion Of Control)中文名爲控制反轉,就是由容器來控制業務對象之間的依賴關係,而非傳統實現中,由代碼直接操控。這也就是所謂“控制反轉”的概念所在:控制權由應用代碼中轉到了外部容器,控制權的轉移,是所謂反轉。控制權的轉移帶來的好處就是降低了業務對象之間的依賴程度。



IoC實現策略:



1) 依賴查找:容器中的受控對象通過容器的API來查找自己所依賴的資源和協作對象。這種方式雖然降低了對象間的依賴,但是同時也使用到了容器的API,造成了我們無法在容器外使用和測試對象。



2) 依賴注入:對象只提供普通的方法讓容器去決定依賴關係,容器全權負責組件的裝配,它會把符合依賴關係的對象通過屬性(JavaBean中的 getter和setter,.NET中的property)或者是構造子傳遞給需要的對象。通過屬性注射依賴關係的做法稱爲設值方法注入(Setter Injection),將構造子參數傳入的做法稱爲構造子注入(Constructor Injection)



IoC的第二種策略 依賴注入是一種更加合適的方法。讓容器去全權負責依賴查詢,受控對象只要暴露屬性和代參數的構造子,使容器可以在初始化對象的時候設置對象間的依賴關係。這種方式往往不需要依賴特定API和接口,完全只要依賴語言本身就可以實現了。Spring之父Rod Johnson稱之爲language-based IoC。



這樣做的好處:

1) 查詢依賴操作和應用代碼分離。

2) 受控對象不會使用到容器的特定的API。這樣我們的受控對象可以搬出容器單獨使用。



現在讓我們來看看依賴注入的兩種實現方法。



(一)設值方法注入(Setter Injection)



使用設值方法注入的時候,受控對象通過屬性來表達自己所依賴的對象和所需配置的值。Java實現中,只要對象提供JavaBean標準的屬性就可以了。例如:

  

public class MyBusinessObject {

private DataSource ds;



public DataSource getDataSource() {

return ds;

}



public void setDataSource(DataSource ds) {

this.ds = ds;

}



// 具體的業務邏輯

}


這樣當容器實例化對象MyBusinessObject的時候,會立即調用設值方法,將所需的DataSource傳遞給MyBusinessObject。



可以看出MyBusinessObject只是一個普通的Java對象,完全沒有依賴IoC容器。這樣它就可以在容器外運行。



(二)構造子注入(Constructor Injection)

如果使用構造子注入MyBusinessObject大概會是這樣的。
   
public class MyBusinessObject {

private DataSource ds;



public MyBusinessObject(DataSource ds) {

this.ds = ds;

}



// 具體的業務邏輯

}


可以看出這也是一個簡單的Java對象,它也同樣不依賴IoC容器。



比起以前在應用代碼中的查找,創建依賴對象的方法來看,這兩種注入方法都有着巨大的進步。但是我們該如何選擇呢。到底是使用設值方法注入還是構造子注入呢。



讓我先來看看這兩種方法的優缺點。



設值方法注入的主要優點:

1) 每個設值方法都有一個對應的讀取方法,這樣就可以要求受控對象彙報自身的狀態。

2) 父類的屬性可以被子類繼承而無需重新編碼。



設值方法注入的主要缺點:

1) 設置方法的調用次序無法規定

2) 在使用對象前,可能存在不是所有的設值方法都會調用到,可能存在着未配置完全的狀態。



構造子注入的主要優點:

1) 在使用之前,對象必定處於配置完全的狀態。

2) 比起多個設值方法來說一個構造函數的代碼量可能更少,當然兩者的複雜程度是沒有區別的。



構造子注入的主要缺點:

1) 構造子無法被自動被繼承。

2) 構造子參數太多和構造子操作太多都不方便於使用

3) IDE對設值方式要比構造子參數列表有更好的支持。



由此可見在下列情況下,設值方法注入更有優勢:

1) 需要配置的屬性很多

2) 對象位於繼承體系中

3) 對象必須提供運行時修改依賴關係的途徑(我認爲這點是最主要的)
發佈了47 篇原創文章 · 獲贊 4 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章