1. IoC是什麼?
html
IoC(Inversion of Control)即控制反轉,不是什麼技術,而是一種設計思想。在Java開發中,IoC 意味着將你設計好的對象交給容器去控制,而不是傳統的在對象內部直接控制(好比說 new 一個對象)。理解好 IoC 的關鍵是要明確「誰控制誰,控制什麼,爲什麼是反轉(有反轉就應該有正轉了),哪些方面反轉了「:java
誰控制誰,控制什麼:傳統Java SE 程序設計,咱們直接在對象內部經過 new 建立對象,是程序主動去建立依賴對象;而 IoC 是由 IoC容器來建立這些對象(在容器啓動的時,容器會初始化 配置文件中定義的 bean,若是 bean 中添加參數 lazy-init="true" 則不會被建立對象); 誰控制誰?固然是 IoC容器控制對象。 控制什麼? 主要控制了外部資源獲取(不僅是對象,也包括文件等。。。)spring
爲什麼是反轉:傳統Java SE 程序設計,咱們直接在對象內部經過 new 建立對象,是程序主動去建立依賴對象,也就是正轉;而反轉則是由容器來建立以及注入依賴對象。下面由兩張圖說明:數據庫
2. IoC 能作什麼
編程
傳統應用程序都是由咱們在類內部主動建立依賴對象,從而致使類與類之間高耦合,增長了維護難度;有了IoC容器後,把建立和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,因此對象與對象之間是鬆散耦合,利於功能複用,更重要的是使得程序的整個體系結構變得很是靈活。spa
其實IoC對編程帶來的最大改變不是從代碼上,而是從思想上,發生了「主從換位」的變化。應用程序本來是老大,要獲取什麼資源都是主動出擊,可是在IoC/DI思想中,應用程序就變成被動的了,被動的等待IoC容器來建立並注入它所須要的資源了。設計
簡單的來講:IoC 容器負責 實例化具體的 Bean,動態裝配這些 Bean到相應的依賴對象中。htm
3. IoC 和 DI對象
IoC的一個重點是:在系統運行過程當中,動態的向某個對象提供它所須要的其餘對象,而這一點是經過DI(Denpendency Injection,即依賴注入)來實現的。IoC 和 DI 是同一個概念的不一樣角度的描述。好比對象A須要操做數據庫,之前咱們老是要在A中本身編寫代碼來得到一個Connection對象,有了 spring咱們就只須要告訴spring,A中須要一個Connection,至於這個Connection怎麼構造,什麼時候構造,A不須要知道。在系統運行時,spring會在適當的時候製造一個Connection,而後像打針同樣,注射到A當中,這樣就完成了對各個對象之間關係的控制。A須要依賴 Connection才能正常運行,而這個Connection是由spring注入到A中的,依賴注入的名字就這麼來的。那麼DI是如何實現的呢? Java 1.3以後一個重要特徵是反射(reflection),它容許程序在運行的時候動態的生成對象、執行對象的方法、改變對象的屬性,spring就是經過反射來實現注入的。blog
DI 是由Martin Fowler 在2004年初的一篇論文中首次提出的。他總結:控制的什麼被反轉了?就是:得到依賴對象的方式反轉了。
還有一篇講解 IoC 容器的文章,很是不錯:http://www.cnblogs.com/xdp-gacl/p/3707631.html,推薦給你們。。。
4. DI 的優勢:
(1)動態替換Bean依賴對象,程序更靈活:替換Bean依賴對象,無需修改源文件:應用依賴注入後,因爲能夠採用配置文件方式實現,從而能隨時動態的替換Bean的依賴對象,無需修改java源文件;
(2)更好實踐面向接口編程,代碼更清晰:在Bean中只需指定依賴對象的接口,接口定義依賴對象完成的功能,經過容器注入依賴實現;
(3)更好實踐優先使用對象組合,而不是類繼承:由於IoC容器採用注入依賴,也就是組合對象,從而更好的實踐對象組合。
(4)採用對象組合,Bean的功能可能由幾個依賴Bean的功能組合而成,其Bean自己可能只提供少量功能或根本無任何功能,所有委託給依賴Bean,對象組合具備動態性,能更方便的替換掉依賴Bean,從而改變Bean功能;
而若是採用類繼承,Bean沒有依賴Bean,而是採用繼承方式添加新功能,,並且功能是在編譯時就肯定了,不具備動態性,並且採用類繼承致使Bean與子Bean之間高度耦合,難以複用。
(5)增長Bean可複用性:依賴於對象組合,Bean更可複用且複用更簡單;
(6)下降Bean之間耦合:因爲咱們徹底採用面向接口編程,在代碼中沒有直接引用Bean依賴實現,所有引用接口,並且不會出現顯示的建立依賴對象代碼,並且這些依賴是由容器來注入,很容易替換依賴實現類,從而下降Bean與依賴之間耦合;
(7)代碼結構更清晰:要應用依賴注入,代碼結構要按照規約方式進行書寫,從而更好的應用一些最佳實踐,所以代碼結構更清晰。
從以上咱們能夠看出,其實依賴注入只是一種裝配對象的手段,設計的類結構纔是基礎,若是設計的類結構不支持依賴注入,Spring IoC容器也注入不了任何東西,從而從根本上說「如何設計好類結構纔是關鍵,依賴注入只是一種裝配對象手段」。