程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 對Spring框架中接口注入理解的實例分析

對Spring框架中接口注入理解的實例分析

編輯:關於JAVA

Type1 接口注入

我們常常借助接口來將調用者與實現者分離。如:

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所用。

這就是接口注入的一個最原始的雛形。

而對於一個Type1型IOC容器而言,加載接口實現並創建其實例的工作由容器完成,如J2EE開發中常用的Context.lookup(ServletContext.getXXX),都是Type1型IOC的表現形式。

apache Avalon是一個典型的Type1型IOC容器。

Type2 構造子注入

構造子注入,即通過構造函數完成依賴關系的設定,如: 字串4

public class DIByConstructor {
  private final DataSource dataSource;
  private final String message;
  public DIByConstructor(DataSource ds, String msg) {
  this.dataSource = ds;
  this.message = msg;
  }
  ……
  }

可以看到,在Type2類型的依賴注入機制中,依賴關系是通過類構造函數建立,容器通過調用類的構造方法,將其所需的依賴關系注入其中。

PicoContainer(另一種實現了依賴注入模式的輕量級容器)首先實現了Type2類型的依賴注入模式。

Type3 設值注入

在各種類型的依賴注入模式中,設值注入模式在實際開發中得到了最廣泛的應用(其中很大一部分得力於Spring框架的影響)。

在筆者看來,基於設置模式的依賴注入機制更加直觀、也更加自然。Quick Start中的示例,就是典型的設置注入,即通過類的setter方法完成依賴關系的設置。

SpringFrameWork Developer’s Guide Version 0.6

September 2, 2004 So many open source projects. Why not Open your Documents?

幾種依賴注入模式的對比總結

字串8

接口注入模式因為具備侵入性,它要求組件必須與特定的接口相關聯,因此並不被看好,實際使用有限。

Type2和Type3的依賴注入實現模式均具備無侵入性的特點。在筆者看來,這兩種實現方式各有特點,也各具優勢(一句經典廢話?)。

Type2 構造子注入的優勢:

1.“在構造期即創建一個完整、合法的對象”,對於這條Java設計原則,Type2無疑是最好的響應者。

我的理解:就是你要通過一種方式來保證對象的引用完整性,type2選擇了構造器的方式來實現。

2. 避免了繁瑣的setter方法的編寫,所有依賴關系均在構造函數中設定,依賴關系集中呈現,更加易讀。

我的理解:使用構造方法就不需要每個屬性都寫set和get方法了,這樣省去了很多的代碼。

3. 由於沒有setter方法,依賴關系在構造時由容器一次性設定,因此組件在被創建之後即處於相對“不變”的穩定狀態,無需擔心上層代碼在調用過程中執行setter方法對組件依賴關系產生破壞,特別是對於Singleton模式的組件而言,這可能對整個系統產生重大的影響。

我的理解:使用構造器來實現,那麼你需要一次對所有的屬性都初始話,相對set方法來說,缺少了一些靈活性。

字串5

4. 同樣,由於關聯關系僅在構造函數中表達,只有組件創建者需要關心組件內部的依賴關系。對調用者而言,組件中的依賴關系處於黑盒之中。對上層屏蔽不必要的信息,也為系統的層次清晰性提供了保證。

我的理解: spring的這設計就是要屏蔽依賴關系,你只需要對接口編程,而不需要考慮依賴關系的實現。所以對調用者來說,依賴關系是處於黑盒當中。

5. 通過構造子注入,意味著我們可以在構造函數中決定依賴關系的注入順序,對於一個大量依賴外部服務的組件而言,依賴關系的獲得順序可能非常重要,比如某個依賴關系注入的先決條件是組件的DataSource及相關資源已經被設定。

我的理解:關於順序問題,我們來看以下兩段代碼:

public DIByConstructor(DataSource ds, String msg) {
  this.dataSource = ds;
  this.message = msg;
  }
  public DIByConstructor(DataSource ds, String msg) {
  this.dataSource = ds;
  this.message = msg;
  }

在本例中,順序不太重要,但是如果message的初始化需要用到datasource 的話,那麼就必須要先初始化datasource,所以相對來說,順序就是確定了。 字串6

Type3 設值注入的優勢

1. 對於習慣了傳統JavaBean開發的程序員而言,通過setter方法設定依賴關系顯得更加直觀,更加自然。

2. 如果依賴關系(或繼承關系)較為復雜,那麼Type2模式的構造函數也會相當龐大(我們需要在構造函數中設定所有依賴關系),此時Type3模式往往更為簡潔。

我的理解:依賴關系(或繼承關系)較為復雜,指的是,屬性較多,需要寫很多的set和get方法。

3. 對於某些第三方類庫而言,可能要求我們的組件必須提供一個默認的構造函數(如Struts中的Action),此時Type2類型的依賴注入機制就體現出其局限性,難以完成我們期望的功能。

可見,Type2和Type3模式各有千秋,而Spring、PicoContainer都對Type2和Type3類型的依賴注入機制提供了良好支持。這也就為我們提供了更多的選擇余地。理論上,以Type2類型為主,輔之以Type3類型機制作為補充,可以達到最好的依賴注入效果,不過對於基於Spring Framework開發的應用而言,Type3使用更加廣泛。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved