Sping三種注入方式
Sping三種注入方式
(本文摘自夏昕:開發指南)
依賴注入的三種實現形式
我們將元件的依賴關係由容器實現,那麼容器如何知道一個元件依賴哪些其它的元件呢?這些回撥方法會告知容器它所依賴的元件。根據回撥方法的不同,我們可以將IoC分為三種形式:
1、 介面注入
簡單的說,介面注入就是在執行期,載入介面實現並建立其例項的工作由容器完成。
如下面這個類:
public class ClassA {
private InterfaceB clzB;
public Object doSomething(InterfaceB b) {
clzB = b;
return clzB.doIt();
}
……
}
在執行期,InterfaceB例項將由容器提供。
Type1型IOC發展較早(有意或無意) ,在實際中得到了普遍應用,即使在IOC的概念尚未確立時,這樣的
方法也已經頻繁出現在我們的程式碼中。
下面的程式碼大家應該非常熟悉:
public class MyServlet extends HttpServlet {
public void doGet(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
……
}
} SpringFrameWork Developer’s Guide Version 0.6
這也是一個Type1 型注入,HttpServletRequest和HttpServletResponse例項由Servlet Container
在執行期動態注入。
另,Apache Avalon是一個較為典型的Type1型IOC容器。
2、 設定注入
在各種型別的依賴注入模式中,設值注入模式在實際開發中得到了最廣泛的應用(其中很大一部分得力於
基於設定模式的依賴注入機制更加直觀、也更加自然。前面的使用者註冊示例,就是典
型的設定注入,即通過類的setter方法完成依賴關係的設定。
3、 構造子函式注入
Type3 構造子注入
構造子注入,即通過建構函式完成依賴關係的設定,如:
public class DIByConstructor {
private final DataSource dataSource;
private final String message;
public DIByConstructor(DataSource ds, String msg) {
this.dataSource = ds;
this.message = msg;
}
……
}
可以看到,在Type3型別的依賴注入機制中,依賴關係是通過類建構函式建立,容器通過呼叫類的構
造方法,將其所需的依賴關係注入其中。
PicoContainer (另一種實現了依賴注入模式的輕量級容器) 首先實現了Type3型別的依賴注入模式
.幾種依賴注入模式的對比總結
介面注入模式因為歷史較為悠久,在很多容器中都已經得到應用。但由於其在靈活性、易用性上不如其他兩種注入模式,因而在IOC的專題世界內並不被看好。
Type2和Type3型的依賴注入實現則是目前主流的IOC實現模式。這兩種實現方式各有特點,也各具優勢(一句經典廢話) 。
Type2 設值注入的優勢
1. 對於習慣了傳統JavaBean開發的程式設計師而言,通過setter方法設定依賴關係顯得更加直
觀,更加自然。
2. 如果依賴關係(或繼承關係)較為複雜,那麼Type3模式的建構函式也會相當龐大(我們需
要在建構函式中設定所有依賴關係) ,此時Type2模式往往更為簡潔。
3. 對於某些第三方類庫而言,可能要求我們的元件必須提供一個預設的建構函式(如Struts
中的Action) ,此時Type3型別的依賴注入機制就體現出其侷限性,難以完成我們期望的功
能。
Type3 構造子注入的優勢:
1. “在構造期即建立一個完整、合法的物件” ,對於這條Java設計原則,Type3無疑是最好的
響應者。
2. 避免了繁瑣的setter方法的編寫,所有依賴關係均在建構函式中設定,依賴關係集中呈現,
更加易讀。
3. 由於沒有setter方法,依賴關係在構造時由容器一次性設定,因此元件在被建立之後即處於
相對“不變”的穩定狀態,無需擔心上層程式碼在呼叫過程中執行setter方法對元件依賴關係
產生破壞,特別是對於Singleton模式的元件而言,這可能對整個系統產生重大的影響。
4. 同樣,由於關聯關係僅在建構函式中表達,只有元件建立者需要關心元件內部的依賴關係。
對呼叫者而言,元件中的依賴關係處於黑盒之中。對上層遮蔽不必要的資訊,也為系統的
層次清晰性提供了保證。
5. 通過構造子注入,意味著我們可以在建構函式中決定依賴關係的注入順序,對於一個大量
依賴外部服務的元件而言,依賴關係的獲得順序可能非常重要,比如某個依賴關係注入的
先決條件是元件的DataSource及相關資源已經被設定。
可見,Type3和Type2模式各有千秋,而Spring、PicoContainer都對Type3和Type2型別的依賴注入機制提供了良好支援。這也就為我們提供了更多的選擇餘地。理論上,以Type3型別為主,輔之以Type2型別機制作為補充,可以達到最好的依賴注入效果,不過對於基於Spring Framework開發的應用而言,Type2使用更加廣泛。