Type 接口注入 我們常常借助接口來將調用者與實現者分離
如:
public class ClassA {
private InterfaceB clzB;
public init() {
Ojbect obj =
Class
forName(Config
BImplementation)
newInstance();
clzB = (InterfaceB)obj;
}
……
}
上面的代碼中
ClassA依賴於InterfaceB的實現
如何獲得InterfaceB實現類的實例?傳統的方法是在代碼中創建InterfaceB實現類的實例
並將起賦予clzB
而這樣一來
ClassA在編譯期即依賴於InterfaceB的實現
為了將調用者與實現者在編譯期分離
於是有了上面的代碼
我們根據預先在配置文件中設定的實現類的類名
動態加載實現類
並通過InterfaceB強制轉型後為ClassA所用
這就是接口注入的一個最原始的雛形
而對於一個Type
型IOC容器而言
加載接口實現並創建其實例的工作由容器完成
如J
EE開發中常用的Context
lookup(ServletContext
getXXX)
都是Type
型IOC的表現形式
Apache Avalon是一個典型的Type
型IOC容器
Type 構造子注入 構造子注入
即通過構造函數完成依賴關系的設定
如
public class DIByConstructor {
private final DataSource dataSource;
private final String message;
public DIByConstructor(DataSource ds
String msg) {
this
dataSource = ds;
ssage = msg;
}
……
}
可以看到
在Type
類型的依賴注入機制中
依賴關系是通過類構造函數建立
容器通過調用類的構造方法
將其所需的依賴關系注入其中
PicoContainer(另一種實現了依賴注入模式的輕量級容器)首先實現了Type
類型的依賴注入模式
Type 設值注入 在各種類型的依賴注入模式中
設值注入模式在實際開發中得到了最廣泛的應用(其中很大一部分得力於Spring框架的影響)
在筆者看來
基於設置模式的依賴注入機制更加直觀
也更加自然
Quick Start中的示例
就是典型的設置注入
即通過類的setter方法完成依賴關系的設置
SpringFrameWork Developer
s Guide Version
September
So many open source projects
Why not Open your Documents?
幾種依賴注入模式的對比總結 接口注入模式因為具備侵入性
它要求組件必須與特定的接口相關聯
因此並不被看好
實際使用有限
Type
和Type
的依賴注入實現模式均具備無侵入性的特點
在筆者看來
這兩種實現方式各有特點
也各具優勢(一句經典廢話?)
Type 構造子注入的優勢 在構造期即創建一個完整
合法的對象
對於這條Java設計原則
Type
無疑是最好的響應者
我的理解
就是你要通過一種方式來保證對象的引用完整性
type
選擇了構造器的方式來實現
避免了繁瑣的setter方法的編寫
所有依賴關系均在構造函數中設定
依賴關系集中呈現
更加易讀
我的理解
使用構造方法就不需要每個屬性都寫set和get方法了
這樣省去了很多的代碼
由於沒有setter方法
依賴關系在構造時由容器一次性設定
因此組件在被創建之後即處於相對
不變
的穩定狀態
無需擔心上層代碼在調用過程中執行setter方法對組件依賴關系產生破壞
特別是對於Singleton模式的組件而言
這可能對整個系統產生重大的影響
我的理解
使用構造器來實現
那麼你需要一次對所有的屬性都初始話
相對set方法來說
缺少了一些靈活性
同樣
由於關聯關系僅在構造函數中表達
只有組件創建者需要關心組件內部的依賴關系
對調用者而言
組件中的依賴關系處於黑盒之中
對上層屏蔽不必要的信息
也為系統的層次清晰性提供了保證
我的理解
spring的這設計就是要屏蔽依賴關系
你只需要對接口編程
而不需要考慮依賴關系的實現
所以對調用者來說
依賴關系是處於黑盒當中
通過構造子注入
意味著我們可以在構造函數中決定依賴關系的注入順序
對於一個大量依賴外部服務的組件而言
依賴關系的獲得順序可能非常重要
比如某個依賴關系注入的先決條件是組件的DataSource及相關資源已經被設定
我的理解
關於順序問題
我們來看以下兩段代碼
public DIByConstructor(DataSource ds
String msg) {
this
dataSource = ds;
ssage = msg;
}
public DIByConstructor(DataSource ds
String msg) {
this
dataSource = ds;
ssage = msg;
}
在本例中
順序不太重要
但是如果message的初始化需要用到datasource 的話
那麼就必須要先初始化datasource
所以相對來說
順序就是確定了
Type 設值注入的優勢 對於習慣了傳統JavaBean開發的程序員而言
通過setter方法設定依賴關系顯得更加直觀
更加自然
如果依賴關系(或繼承關系)較為復雜
那麼Type
模式的構造函數也會相當龐大(我們需要在構造函數中設定所有依賴關系)
此時Type
模式往往更為簡潔
我的理解
依賴關系(或繼承關系)較為復雜
指的是
屬性較多
需要寫很多的set和get方法
對於某些第三方類庫而言
可能要求我們的組件必須提供一個默認的構造函數(如Struts中的Action)
此時Type
類型的依賴注入機制就體現出其局限性
難以完成我們期望的功能
可見
Type
和Type
模式各有千秋
而Spring
PicoContainer都對Type
和Type
類型的依賴注入機制提供了良好支持
這也就為我們提供了更多的選擇余地
理論上
以Type
類型為主
輔之以Type
類型機制作為補充
可以達到最好的依賴注入效果
不過對於基於Spring Framework開發的應用而言
Type
使用更加廣泛
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28069.html