天天看點

1、Spring架構-IoC與DI

剛開始學習Spring,對這些概念很生,查了很多資料,如下是比較好的,現總結記錄如下:

1.1、IoC是什麼

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

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

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

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

1、Spring架構-IoC與DI

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

  當有了IoC/DI的容器後,在用戶端類中不再主動去建立這些對象了,如圖2-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的架構中堆積木而已。

3.另一篇文章

淺談控制反轉(Inversion of Control,IOC)

  我們首先先來了解一下控制二字,也就是在控制“正”轉的情況下,在任何一個有請求作用的系統當中,至少需要有兩個類互相配合工作,在一個入口類下使用new關鍵字建立另一個類的對象執行個體,這就好比在面向對象程式設計的思想下,“我“充當一個入口類,在這個入口類中,我每次吃飯的時候都要買一雙一次性筷子(每一次使用都要new一次),在這樣的關系下,是”我“(即調用者)每次都要”主動“去買一次性筷子(另一個類),我對筷子說你老老實實的過來我的手上,是我控制了筷子,那好,在這種控制正轉的關系下,放在現實生活當中,肯定是不現實的,而且人是懶惰的,他總會去創造出更加友善自己生活的想法,更确切的做法是,買一雙普通的筷子(非一次性),把他放在一個容器當中(在Spring中叫做IOC容器),你需要使用的時候就對容器說:IOC我想要用筷子(向容器送出請求),接着筷子就會”注入“到的手上,而在這個過程當中,你不再是控制方,反而演變成一名請求者(雖然本身還是調用者),依賴于容器給予你資源,控制權坐落到了容器身上,于是這就是人們俗稱的控制反轉。

 初涉依賴注入(Dependency Injection)  

  同樣接着上面的例子,在控制反轉的統一下,筷子是怎麼來到我的手上(即我們是如何獲得請求的類),這就是一個依賴注入的過程。

1、Spring架構-IoC與DI

 再談IOC與DI

  設計原則中好萊塢原則描述到,“别找我們,我們找你”,百度百科上對這點描述是“不要給我們打電話,我們會給你打電話(don‘t call us, we‘ll call you)”這是著名的好萊塢原則。在好萊塢,把履歷遞交給演藝公司後就隻有回家等待。由演藝公司對整個娛樂項的完全控制,演員隻能被動式的接受公司的差使,在需要的環節中,完成自己的演出。這一點完美的提現了在IOC身上,IOC所注重的是設計思想上,從一個正常的建立對象的做法,即new一個對象,轉變成向IOC容器遞交”履歷“,被動的等待IOC容器傳回資源給你。控制反轉即指的是”演藝公司控制演員“,而說到依賴,則是“演員需要公司混飯”,我們所需求的對象,需要依賴容器來獲得,這個過程即是依賴注入。本質上IOC和DI是同一思想下不同次元的表現。

繼續閱讀