學(xué)習(xí)過Spring框架的人一定都會聽過Spring的IoC(控制反轉(zhuǎn)) 、DI(依賴注入)這兩個概念,對于初學(xué)Spring的人來說,總覺得IoC 、DI這兩個概念是模糊不清的,是很難理解的,今天和大家分享網(wǎng)上的一些技術(shù)大牛們對Spring框架的IOC的理解以及談?wù)勎覍pring Ioc的理解。
創(chuàng)新互聯(lián)公司主營漢川網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,成都app軟件開發(fā),漢川h5小程序設(shè)計搭建,漢川網(wǎng)站營銷推廣歡迎漢川等地區(qū)企業(yè)咨詢
IoC是什么
Ioc—InversionofControl,即“控制反轉(zhuǎn)”,不是什么技術(shù),而是一種設(shè)計思想。在Java開發(fā)中,Ioc意味著將你設(shè)計好的對象交給容器控制,而不是傳統(tǒng)的在你的對象內(nèi)部直接控制。
IoC,這是spring的核心,貫穿始終。所謂IoC,對于spring框架來說,就是由spring來負(fù)責(zé)控制對象的生命周期和對象間的關(guān)系。這是什么意思呢,舉個簡單的例子,我們是如何找女朋友的?常見的情況是,我們到處去看哪里有長得漂亮身材又好的mm,然后打聽她們的興趣愛好、qq號、電話號、ip號、iq號………,想辦法認(rèn)識她們,投其所好送其所要,然后嘿嘿……這個過程是復(fù)雜深奧的,我們必須自己設(shè)計和面對每個環(huán)節(jié)。傳統(tǒng)的程序開發(fā)也是如此,在一個對象中,如果要使用另外的對象,就必須得到它(自己new一個,或者從JNDI中查詢一個),使用完之后還要將對象銷毀(比如Connection等),對象始終會和其他的接口或類藕合起來。
如何理解好Ioc呢?理解好Ioc的關(guān)鍵是要明確“誰控制誰,控制什么,為何是反轉(zhuǎn)(有反轉(zhuǎn)就應(yīng)該有正轉(zhuǎn)了),哪些方面反轉(zhuǎn)了”,那我們來深入分析一下:
●誰控制誰,控制什么:傳統(tǒng)JavaSE程序設(shè)計,我們直接在對象內(nèi)部通過new進(jìn)行創(chuàng)建對象,是程序主動去創(chuàng)建依賴對象;而IoC是有專門一個容器來創(chuàng)建這些對象,即由Ioc容器來控制對象的創(chuàng)建;誰控制誰?當(dāng)然是IoC容器控制了對象;控制什么?那就是主要控制了外部資源獲取(不只是對象包括比如文件等)。
●為何是反轉(zhuǎn),哪些方面反轉(zhuǎn)了:有反轉(zhuǎn)就有正轉(zhuǎn),傳統(tǒng)應(yīng)用程序是由我們自己在對象中主動控制去直接獲取依賴對象,也就是正轉(zhuǎn);而反轉(zhuǎn)則是由容器來幫忙創(chuàng)建及注入依賴對象;為何是反轉(zhuǎn)?因?yàn)橛扇萜鲙臀覀儾檎壹白⑷胍蕾噷ο螅瑢ο笾皇潜粍拥慕邮芤蕾噷ο螅允欠崔D(zhuǎn);哪些方面反轉(zhuǎn)了?依賴對象的獲取被反轉(zhuǎn)了。
用圖例說明一下,傳統(tǒng)程序設(shè)計如圖1-1,都是主動去創(chuàng)建相關(guān)對象然后再組合起來:
圖1-1 傳統(tǒng)應(yīng)用程序示意圖
當(dāng)有了IoC/DI的容器后,在客戶端類中不再主動去創(chuàng)建這些對象了,如圖1-2所示:
圖1-2有IoC/DI容器后程序結(jié)構(gòu)示意圖
1.1.2IoC能做什么
IoC不是一種技術(shù),只是一種思想,一個重要的面向?qū)ο缶幊痰姆▌t,它能指導(dǎo)我們?nèi)绾卧O(shè)計出松耦合、更優(yōu)良的程序。傳統(tǒng)應(yīng)用程序都是由我們在類內(nèi)部主動創(chuàng)建依賴對象,從而導(dǎo)致類與類之間高耦合,難于測試;有了IoC容器后,把創(chuàng)建和查找依賴對象的控制權(quán)交給了容器,由容器進(jìn)行注入組合對象,所以對象與對象之間是松散耦合,這樣也方便測試,利于功能復(fù)用,更重要的是使得程序的整個體系結(jié)構(gòu)變得非常靈活。
其實(shí)IoC對編程帶來的最大改變不是從代碼上,而是從思想上,發(fā)生了“主從換位”的變化。應(yīng)用程序原本是老大,要獲取什么資源都是主動出擊,但是在IoC/DI思想中,應(yīng)用程序就變成被動的了,被動的等待IoC容器來創(chuàng)建并注入它所需要的資源了。
IoC很好的體現(xiàn)了面向?qū)ο笤O(shè)計法則之一——好萊塢法則:“別找我們,我們找你”;即由IoC容器幫對象找相應(yīng)的依賴對象并注入,而不是由對象主動去找。
1.1.3IoC和DI
DI—DependencyInjection,即“依賴注入”:是組件之間依賴關(guān)系由容器在運(yùn)行期決定,形象的說,即由容器動態(tài)的將某個依賴關(guān)系注入到組件之中。依賴注入的目的并非為軟件系統(tǒng)帶來更多功能,而是為了提升組件重用的頻率,并為系統(tǒng)搭建一個靈活、可擴(kuò)展的平臺。通過依賴注入機(jī)制,我們只需要通過簡單的配置,而無需任何代碼就可指定目標(biāo)需要的資源,完成自身的業(yè)務(wù)邏輯,而不需要關(guān)心具體的資源來自何處,由誰實(shí)現(xiàn)。
IoC的一個重點(diǎn)是在系統(tǒng)運(yùn)行中,動態(tài)的向某個對象提供它所需要的其他對象。這一點(diǎn)是通過DI(Dependency Injection,依賴注入)來實(shí)現(xiàn)的。比如對象A需要操作數(shù)據(jù)庫,以前我們總是要在A中自己編寫代碼來獲得一個Connection對象,有了 spring我們就只需要告訴spring,A中需要一個Connection,至于這個Connection怎么構(gòu)造,何時構(gòu)造,A不需要知道。在系統(tǒng)運(yùn)行時,spring會在適當(dāng)?shù)臅r候制造一個Connection,然后像打針一樣,注射到A當(dāng)中,這樣就完成了對各個對象之間關(guān)系的控制。A需要依賴 Connection才能正常運(yùn)行,而這個Connection是由spring注入到A中的,依賴注入的名字就這么來的。那么DI是如何實(shí)現(xiàn)的呢? Java 1.3之后一個重要特征是反射(reflection),它允許程序在運(yùn)行的時候動態(tài)的生成對象、執(zhí)行對象的方法、改變對象的屬性,spring就是通過反射來實(shí)現(xiàn)注入的。
理解DI的關(guān)鍵是:“誰依賴誰,為什么需要依賴,誰注入誰,注入了什么”,那我們來深入分析一下:
●誰依賴于誰:當(dāng)然是應(yīng)用程序依賴于IoC容器;
●為什么需要依賴:應(yīng)用程序需要IoC容器來提供對象需要的外部資源;
●誰注入誰:很明顯是IoC容器注入應(yīng)用程序某個對象,應(yīng)用程序依賴的對象;
●注入了什么:就是注入某個對象所需要的外部資源(包括對象、資源、常量數(shù)據(jù))。
IoC和DI由什么關(guān)系呢?其實(shí)它們是同一個概念的不同角度描述,由于控制反轉(zhuǎn)概念比較含糊(可能只是理解為容器控制對象這一個層面,很難讓人想到誰來維護(hù)對象關(guān)系),所以2004年大師級人物MartinFowler又給出了一個新的名字:“依賴注入”,相對IoC而言,“依賴注入”明確描述了“被注入對象依賴IoC容器配置依賴對象”。
總結(jié)
其實(shí)對于Spring IOC這個概念,每個人都有自己的理解,并沒有標(biāo)準(zhǔn)答案,大致方向沒錯即可。
以上就是本文關(guān)于理解Spring中的依賴注入和控制反轉(zhuǎn)的全部內(nèi)容,希望對大家有所幫助。如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!