Spring學習筆記(1.2):什麼是依賴查找,依賴查找的實現方式

本文是我學習的一個總結


#a這片文章是對自己學習的總結。


1、什麼是依賴注入

簡單回憶一下控制反轉的概念(IOC)。

開發過程中,我們在一個類中的代碼常常會依賴到其他的類對象。比如下面的service類需要用到dao類提供的操作數據庫的方法,也就是service依賴dao。沒有dao,service的一些方法就沒法進行下去。

既然需要這個類對象,那最簡單的方式就是直接去new出來。

public class ServiceImpl implements Service {
	public void insertData(String data) {
		//直接new
		Dao dao = new Dao();
		dao.insert(data);
	}
}

這裏ServiceImpl和Dao產生了依賴關係,ServiceImpl依賴Dao。這種情況下,ServiceImpl需要Dao的時候,ServiceImpl是主動去創建一個dao對象(注意是主動創造)。

這種主動創建的行爲會帶來一些麻煩。因爲代碼已經寫死了,A和B是直接耦合在一起的。如果以後因爲業務需求,類B的創建出現了一些問題,比如無法直接new,構造器被隱藏設爲私有。等業務人員改完B的代碼,重新啓動項目後發現A開始報錯,又不得不去處理A的邏輯。看到了吧,我們只是想修改B的邏輯,但因爲一些依賴關係又不得不去處理很多”原本不應該管的邏輯“。可以想象。這樣的依賴關係如果多了的話,那後期維護代碼會變得舉步維艱。

仔細想想,A和B的依賴中,A只是想要B的服務。A其實不需要關係B的創建過程,只要有個B的對象來提供服務就好。

正是有了這個突破點,控制反轉的概念順勢而出,即當類A與類B產生依賴關係時(A需要B),不需要A去主動創建B,而是交給外界創建好B對象,然後通過一些方式把B對象交給A使用。

控制反轉的意思是將創建B這個行爲的主動權從需要方類A的手中反轉到其他人手中。

只是外界創建好依賴對象B後,A可以通過多種方式獲取到B。其中,A通過容器主動查找的方法,被稱爲依賴查找。


2、依賴查找的實現方式

依賴查找有兩種實現方式,依賴拖曳和上下文查找。在介紹這兩種實現方式之前,要記住依賴查找是當A依賴到B時,A主動向容器中查找B對象(getBean()方法)。依賴拖曳和上下文查找都是這樣獲取依賴的。兩者的不同之處在於如何選擇和獲取到容器。

2.1 依賴拖曳(Dependency Pull)

依賴拖曳獲取容器的方法是在代碼中寫死的。其邏輯是從配置文件(.properties,xml文件等)中生成容器,然後再從容器中查找需要的依賴對象。也就是說,依賴對象必須在指定的配置文件中配置好。

我們來改造文章開頭的例子,從代碼中看看依賴拖曳如何獲取依賴的。

public class ServiceImpl implements Service {
	public void insertData(String data) {
		//注意getFactory方法,依賴拖曳和上下文查找只有getFactory的實現不同而已
		BeanFactory beanFactory = getFactory();
		//得到容器後直接getBean方法查找依賴對象
		Dao dao = (Dao) beanFactory.getBean("dao");
		dao.insert(data);
	}
	
	private BeanFactory getBeanFactory() {
		//從指定配置文件中獲取容器
		XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));
		return beanFactory;
	}
}

2.2 上下文查找

顧名思義,上下文查找的查找方式是和當前環境有關的。與依賴拖曳那樣永遠通過指定容器的方式不同,上下文查找獲取容器的方式是動態的,是由外界傳來的。

我們還是以代碼爲例。

public class ServiceImpl implements Service {
	//在方法中傳入beanFactory,這就不是從指定配置文件中獲取beanFactory了。
	public void insertData(String data, BeanFactroy beanFactory) {
		Dao dao = (Dao) beanFactory.getBean("dao");
		dao.insert(data);
	}
}

從代碼中可以看出,beanFactory是由外界傳來的。那這個beanFactory的來源就不是固定的了,這一點和依賴拖曳不同。


3、依賴注入(DI)和依賴查找(DL)的比較

關於依賴注入的介紹可以看這篇文章

兩者都是符合IoC的一個原則,(A的邏輯中需要B的服務,A依賴B。A是依賴對象,B是被依賴對象)即被依賴對象不再由依賴對象主動創建,創建管理被依賴對象的工作交給容器,依賴對象只管用就行了。

DI和DL相比較,很明顯DI的處理方式更符合IoC的思想。畢竟IoC理念提出來就是爲了解決耦合問題,讓開發人員更專注於業務代碼而不用考慮與業務無關的依賴等問題。

從依賴查找的的實現方式中我們可以看到,依賴查找對業務代碼是有侵入性的。業務代碼中必須包含着獲取beanFactory的容器的邏輯,而獲取beanFactory明顯不屬於業務邏輯。

依賴查找唯一比依賴注入好的地方,就是代碼的邏輯比較明顯。我們能從代碼中很明顯地看到被依賴對象是從容器中來的,而如何獲取到容器也是顯而易見的。但依賴查找就沒那麼明顯,被依賴對象的注入方式寫得比較隱晦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章