談談對Spring IOC的理解(轉)

来源:http://www.cnblogs.com/zhangzongle/archive/2016/09/24/5904368.html
-Advertisement-
Play Games

學習過Spring框架的人一定都會聽過Spring的IoC(控制反轉) 、DI(依賴註入)這兩個概念,對於初學Spring的人來說,總覺得IoC 、DI這兩個概念是模糊不清的,是很難理解的,今天和大家分享網上的一些技術大牛們對Spring框架的IOC的理解以及談談我對Spring Ioc的理解。 一 ...


學習過Spring框架的人一定都會聽過Spring的IoC(控制反轉) 、DI(依賴註入)這兩個概念,對於初學Spring的人來說,總覺得IoC 、DI這兩個概念是模糊不清的,是很難理解的,今天和大家分享網上的一些技術大牛們對Spring框架的IOC的理解以及談談我對Spring Ioc的理解。

一、分享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 容器控制了對象;控制什麼?那就是主要控制了外部資源獲取(不只是對象包括比如文件等)。

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

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

圖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的框架中堆積木而已。

三、我對IoC(控制反轉)和DI(依賴註入)的理解

  在平時的java應用開發中,我們要實現某一個功能或者說是完成某個業務邏輯時至少需要兩個或以上的對象來協作完成,在沒有使用Spring的時候,每個對象在需要使用他的合作對象時,自己均要使用像new object() 這樣的語法來將合作對象創建出來,這個合作對象是由自己主動創建出來的,創建合作對象的主動權在自己手上,自己需要哪個合作對象,就主動去創建,創建合作對象的主動權和創建時機是由自己把控的,而這樣就會使得對象間的耦合度高了,A對象需要使用合作對象B來共同完成一件事,A要使用B,那麼A就對B產生了依賴,也就是A和B之間存在一種耦合關係,並且是緊密耦合在一起,而使用了Spring之後就不一樣了,創建合作對象B的工作是由Spring來做的,Spring創建好B對象,然後存儲到一個容器裡面,當A對象需要使用B對象時,Spring就從存放對象的那個容器裡面取出A要使用的那個B對象,然後交給A對象使用,至於Spring是如何創建那個對象,以及什麼時候創建好對象的,A對象不需要關心這些細節問題(你是什麼時候生的,怎麼生出來的我可不關心,能幫我幹活就行),A得到Spring給我們的對象之後,兩個人一起協作完成要完成的工作即可。

  所以控制反轉IoC(Inversion of Control)是說創建對象的控制權進行轉移,以前創建對象的主動權和創建時機是由自己把控的,而現在這種權力轉移到第三方,比如轉移交給了IoC容器,它就是一個專門用來創建對象的工廠,你要什麼對象,它就給你什麼對象,有了 IoC容器,依賴關係就變了,原先的依賴關係就沒了,它們都依賴IoC容器了,通過IoC容器來建立它們之間的關係。

  這是我對Spring的IoC(控制反轉)的理解。DI(依賴註入)其實就是IOC的另外一種說法,DI是由Martin Fowler 在2004年初的一篇論文中首次提出的。他總結:控制的什麼被反轉了?就是:獲得依賴對象的方式反轉了。

四、小結

  對於Spring Ioc這個核心概念,我相信每一個學習Spring的人都會有自己的理解。這種概念上的理解沒有絕對的標準答案,仁者見仁智者見智。如果有理解不到位或者理解錯的地方,歡迎廣大園友指正!

 

轉:http://www.cnblogs.com/xdp-gacl/p/4249939.html

謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 類型參數使得設計類和方法時,不必確定一個或多個具體參數,其的具體參數可延遲到客戶代碼中聲明、實現。 這意味著使用泛型的類型參數T,寫一個類MyList<T>,客戶代碼可以這樣調用:MyList<int>, MyList<string>或 MyList<MyClass>。 這避免了運行時類型轉換或裝箱 ...
  • 一、說明 1) 這個類 是我 在真實項目中,優化解決真實問題 時,不參考第三方代碼,完全由自己查閱MSDN官方文檔 , 完成的一個真實生產環境中使用的功能類 2) 讀者在使用此類時,請尊重原創,在代碼中加上原創註釋:// Author -- Meng.NET (cnblogs.com) ,同時歡迎 ...
  • 內置對象: Response對象:響應請求 Response.Write("<script>alert('添加成功!')</script>"); Response.Redirect("Default.aspx"); Request對象:獲取請求 Request["key"]來獲取傳遞過來的值 Que ...
  • 回到目錄 我們知道mvc里有一些過濾器,AuthorizeAttribute用來做授權,一般在用戶授權方面可以使用它,當使用沒有登陸,我們直接跳到登陸頁,這是沒有問題的,可我要說的是,當用戶對某個Action沒有許可權時,如何禁止對當前action的執行,這個聽起來很不可思議,因為我們一般感覺,當Au ...
  • httpModules是往當前應用程式添加HttpModule(http模塊)的標簽。配置節如下 提起httpModule不得不提一下Http請求處理流程 ASP.NET對請求處理的過程: 當請求一個*.aspx文件的時候,這個請求會被inetinfo.exe進程截獲,它判斷文件的尾碼(aspx)之 ...
  • Response對象:響應請求 Response.Write("<script>alert('添加成功!')</script>"); Response.Redirect("Default.aspx"); Request對象:獲取請求 Request["key"]來獲取傳遞過來的值 QueryStri ...
  • 佈局:有2個屬性: Anchor:鎖定位置Dock:填充位置一般Dock是與容器控制項配合使用 容器控制項:Panel:就是一個區域,類似於DIV,可以獨立佈局,還可以讓其它控制項及容器在它的內部再次佈局 FlowLayoutPanel:流式佈局容器,內容會預設從左向右排列,如果寬度不夠了,那麼自動換行 ...
  • The alias cmd list your current aliases. For example : alias Use alias to shorten a long cmd in current shell session: alias [name=['command']] Use un... ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...