Spring系列(二):Spring IoC/DI的理解


       這幾天重新學習了一下Spring,在網上找了相關的ppt來看,當看到Spring IoC這一章節的時候,先大致瀏覽了一下內容,有將近50頁的內容,內心竊喜~QAQ~,看完這些內容能夠對IoC有更深層次的理解。然並卵,花了兩天的時間終於看完了,還自己寫了示例代碼,可是對IoC的理解還是一臉懵逼,這時就想到了度娘,果然度娘還是很強大的,找到一篇關於Spring IoC的理解的文章,讀完這篇文章后豁然開朗,如沐春風。下面我們就一起來看看這篇文章:http://www.cnblogs.com/xdp-gacl/p/4249939.html

一、分享Iteye的開濤對Ioc的精彩講解

  首先要分享的是Iteye的開濤這位技術牛人對Spring框架的IOC的理解,寫得非常通俗易懂,以下內容全部來自原文,原文地址:http://jinnianshilongnian.iteye.com/blog/1413846

1.1、IoC是什么

  Ioc—Inversion of Control,即“控制反轉”,不是什么技術,而是一種設計思想。在Java開發中,Ioc意味着將你設計好的對象交給容器控制,而不是傳統的在你的對象內部直接控制。如何理解好Ioc呢?理解好Ioc的關鍵是要明確“誰控制誰,控制什么,為何是反轉(有反轉就應該有正轉了),哪些方面反轉了”,那我們來深入分析一下:

  ●誰控制誰,控制什么:傳統Java SE程序設計,我們直接在對象內部通過new進行創建對象,是程序主動去創建依賴對象;而IoC是有專門一個容器來創建這些對象,即由Ioc容器來控制對 象的創建;誰控制誰?當然是IoC 容器控制了對象;控制什么?那就是主要控制了外部資源獲取(不只是對象包括比如文件等)。

  ●為何是反轉,哪些方面反轉了:有反轉就有正轉,傳統應用程序是由我們自己在對象中主動控制去直接獲取依賴對象,也就是正轉;而反轉則是由容器來幫忙創建及注入依賴對象;為何是反轉?因為由容器幫我們查找及注入依賴對象,對象只是被動的接受依賴對象,所以是反轉;哪些方面反轉了?依賴對象的獲取被反轉了。

  用圖例說明一下,傳統程序設計如圖1-1,都是主動去創建相關對象然后再組合起來:

圖1-1 傳統應用程序示意圖

  當有了IoC/DI的容器后,在客戶端類中不再主動去創建這些對象了,如圖1-2所示:

圖1-2有IoC/DI容器后程序結構示意圖

1.2、IoC能做什么

  IoC 不是一種技術,只是一種思想,一個重要的面向對象編程的法則,它能指導我們如何設計出松耦合、更優良的程序。傳統應用程序都是由我們在類內部主動創建依賴對象,從而導致類與類之間高耦合,難於測試;有了IoC容器后,把創建和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,所以對象與對象之間是 松散耦合,這樣也方便測試,利於功能復用,更重要的是使得程序的整個體系結構變得非常靈活。

  其實IoC對編程帶來的最大改變不是從代碼上,而是從思想上,發生了“主從換位”的變化。應用程序原本是老大,要獲取什么資源都是主動出擊,但是在IoC/DI思想中,應用程序就變成被動的了,被動的等待IoC容器來創建並注入它所需要的資源了。

  IoC很好的體現了面向對象設計法則之一—— 好萊塢法則:“別找我們,我們找你”;即由IoC容器幫對象找相應的依賴對象並注入,而不是由對象主動去找。

1.3、IoC和DI

  DI—Dependency Injection,即“依賴注入”組件之間依賴關系由容器在運行期決定,形象的說,即由容器動態的將某個依賴關系注入到組件之中依賴注入的目的並非為軟件系統帶來更多功能,而是為了提升組件重用的頻率,並為系統搭建一個靈活、可擴展的平台。通過依賴注入機制,我們只需要通過簡單的配置,而無需任何代碼就可指定目標需要的資源,完成自身的業務邏輯,而不需要關心具體的資源來自何處,由誰實現。

  理解DI的關鍵是:“誰依賴誰,為什么需要依賴,誰注入誰,注入了什么”,那我們來深入分析一下:

  ●誰依賴於誰:當然是應用程序依賴於IoC容器

  ●為什么需要依賴:應用程序需要IoC容器來提供對象需要的外部資源

  ●誰注入誰:很明顯是IoC容器注入應用程序某個對象,應用程序依賴的對象

  ●注入了什么:就是注入某個對象所需要的外部資源(包括對象、資源、常量數據)

  IoC和DI由什么關系呢?其實它們是同一個概念的不同角度描述,由於控制反轉概念比較含糊(可能只是理解為容器控制對象這一個層面,很難讓人想到誰來維護對象關系),所以2004年大師級人物Martin Fowler又給出了一個新的名字:“依賴注入”,相對IoC 而言,依賴注入”明確描述了“被注入對象依賴IoC容器配置依賴對象”。

  看過很多對Spring的Ioc理解的文章,好多人對Ioc和DI的解釋都晦澀難懂,反正就是一種說不清,道不明的感覺,讀完之后依然是一頭霧水,感覺就是開濤這位技術牛人寫得特別通俗易懂,他清楚地解釋了IoC(控制反轉) 和DI(依賴注入)中的每一個字,讀完之后給人一種豁然開朗的感覺。我相信對於初學Spring框架的人對Ioc的理解應該是有很大幫助的。

二、分享Bromon的blog上對IoC與DI淺顯易懂的講解

2.1、IoC(控制反轉)

  首先想說說IoC(Inversion of Control,控制反轉)。這是spring的核心,貫穿始終。所謂IoC,對於spring框架來說,就是由spring來負責控制對象的生命周期和對象間的關系。這是什么意思呢,舉個簡單的例子,我們是如何找女朋友的?常見的情況是,我們到處去看哪里有長得漂亮身材又好的mm,然后打聽她們的興趣愛好、qq號、電話號、ip號、iq號………,想辦法認識她們,投其所好送其所要,然后嘿嘿……這個過程是復雜深奧的,我們必須自己設計和面對每個環節。傳統的程序開發也是如此,在一個對象中,如果要使用另外的對象,就必須得到它(自己new一個,或者從JNDI中查詢一個),使用完之后還要將對象銷毀(比如Connection等),對象始終會和其他的接口或類藕合起來。

  那么IoC是如何做的呢?有點像通過婚介找女朋友,在我和女朋友之間引入了一個第三者:婚姻介紹所。婚介管理了很多男男女女的資料,我可以向婚介提出一個列表,告訴它我想找個什么樣的女朋友,比如長得像李嘉欣,身材像林熙雷,唱歌像周傑倫,速度像卡洛斯,技術像齊達內之類的,然后婚介就會按照我們的要求,提供一個mm,我們只需要去和她談戀愛、結婚就行了。簡單明了,如果婚介給我們的人選不符合要求,我們就會拋出異常。整個過程不再由我自己控制,而是有婚介這樣一個類似容器的機構來控制。Spring所倡導的開發方式就是如此,所有的類都會在spring容器中登記,告訴spring你是個什么東西,你需要什么東西,然后spring會在系統運行到適當的時候,把你要的東西主動給你,同時也把你交給其他需要你的東西。所有的類的創建、銷毀都由 spring來控制,也就是說控制對象生存周期的不再是引用它的對象,而是spring。對於某個具體的對象而言,以前是它控制其他對象,現在是所有對象都被spring控制,所以這叫控制反轉。

2.2、DI(依賴注入)

  IoC的一個重點是在系統運行中,動態的向某個對象提供它所需要的其他對象。這一點是通過DI(Dependency Injection,依賴注入)來實現的。比如對象A需要操作數據庫,以前我們總是要在A中自己編寫代碼來獲得一個Connection對象,有了 spring我們就只需要告訴spring,A中需要一個Connection,至於這個Connection怎么構造,何時構造,A不需要知道。在系統運行時,spring會在適當的時候制造一個Connection,然后像打針一樣,注射到A當中,這樣就完成了對各個對象之間關系的控制。A需要依賴 Connection才能正常運行,而這個Connection是由spring注入到A中的,依賴注入的名字就這么來的。那么DI是如何實現的呢? Java 1.3之后一個重要特征是反射(reflection),它允許程序在運行的時候動態的生成對象、執行對象的方法、改變對象的屬性,spring就是通過反射來實現注入的。

  理解了IoC和DI的概念后,一切都將變得簡單明了,剩下的工作只是在spring的框架中堆積木而已。

三、小結

        上面對Spring IoC的理解,我個人更傾向於第二種,因為第二種更加逗比,通俗易懂!不扯犢子了,談談我對Spring IoC的理解:有了Spring IoC以后,我們不再像傳統java編程那樣,自己去創建需要的一個或者多個對象實例了,所有依賴的對象實例都交給IoC容器去創建和管理,然后把依賴的對象注入到當前對象中。因為對象的創建和管理都交給了Spring的IoC容器來完成,不再像傳統編程那樣需要自己去new了,從而降低了耦合度 。

               


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM