若是在Class A 中,有Class B 的實例,則稱Class A 對Class B 有一個依賴。例以下面類Human 中用到一個Father 對象,咱們就說類Human 對類Father 有一個依賴。java
public class Human { ... Father father; ... public Human() { father = new Father(); } }
仔細看這段代碼咱們會發現存在一些問題:
(1).若是如今要改變father生成方式,如須要用new Father(String name)
初始化father,須要修改Human代碼;
(2).若是想測試不一樣Father對象對Human的影響很困難,由於father的初始化被寫死在了Human的構造函數中;
(3).若是new Father()
過程很是緩慢,單測時咱們但願用已經初始化好的father對象Mock掉這個過程也很困難。spring
上面將依賴在構造函數中直接初始化是一種Hard init 方式,弊端在於兩個類不夠獨立,不方便測試。咱們還有另一種Init 方式,以下:設計模式
public class Human { ... Father father; ... public Human(Father father) { this.father = father; } }
上面代碼中,咱們將father對象做爲構造函數的一個參數傳入。在調用Human的構造方法以前外部就已經初始化好了Father對象。像這種非本身主動初始化依賴,而經過外部來傳入依賴的方式,咱們就稱爲依賴注入。
如今咱們發現上面1中存在的兩個問題都很好解決了,簡單的說依賴注入主要有兩個好處:
(1).解耦,將依賴之間解耦。
(2).由於已經解耦,因此方便作單元測試,尤爲是Mock測試框架
固然,在java中比較簡便的方式是經過註解進行依賴注入。函數
2.實現單元測試
依賴注入的實現是經過java的反射原理。像在spring框架中使用的依賴注入,原理就是從xml中讀取到類的名稱,而後經過反射進行類的實例化,而且同時使用單例、共工廠等設計模式。測試