探祕 Spring IoC

2020-08-11 20:18:18

前言:

在这里插入图片描述

  • 在採用物件導向方法設計的軟件系統中,它的底層實現都是由N個物件組成的,所有的物件通過彼此的合作,最終實現系統的業務邏輯。齒輪組中齒輪之間的齧合關係,與軟件系統中物件之間的耦合關係非常相似。物件之間的耦合關係是無法避免的,也是必要的,這是協同工作的基礎。
  • 爲了解決物件之間的耦合度過高的問題,軟體專家Michael Mattson提出了IOC理論,用來實現物件之間的「解耦」,目前這個理論已經被成功地應用到實踐當中,很多的J2EE專案均採用了IOC框架產品Spring。

一. 什麼是控制反轉(IoC)

  • IOC是Inversion of Control的縮寫,多數書籍翻譯成「控制反轉」,還有些書籍翻譯成爲「控制反向」或者「控制倒置」。
  • 簡單來說就是把複雜系統分解成相互合作的物件,這些物件類通過封裝以後,內部實現對外部是透明的,從而降低瞭解決問題的複雜度,而且可以靈活地被重用和擴充套件。
  • IOC理論提出的觀點大體是這樣的:藉助於「第三方」實現具有依賴關係的物件之間的解耦,如下圖:

在这里插入图片描述

  • 引進了中間位置的「第三方」,也就是IOC容器,使得A、B、C、D這4個物件沒有了耦合關係,齒輪之間的傳動全部依靠「第三方」了,全部物件的控制權全部上繳給「第三方」IOC容器,所以,IOC容器成了整個系統的關鍵核心,它起到了一種類似「粘合劑」的作用,把系統中的所有物件粘合在一起發揮作用,如果沒有這個「粘合劑」,物件與物件之間會彼此失去聯繫,這就是有人把IOC容器比喻成「粘合劑」的由來。
  • 我們再來做個試驗:把上圖中間的IOC容器拿掉,然後再來看看這套系統:
    在这里插入图片描述
    控制反轉(IOC)–到底爲什麼要起這麼個名字?我們來對比一下:
  • 軟件系統在沒有引入IOC容器之前,如圖1所示,物件A依賴於物件B,那麼物件A在初始化或者執行到某一點的時候,自己必須主動去建立物件B或者使用已經建立的物件B。無論是建立還是使用物件B,控制權都在自己手上。
  • 軟件系統在引入IOC容器之後,這種情形就完全改變了,如圖3所示,由於IOC容器的加入,物件A與物件B之間失去了直接聯繫,所以,當物件A執行到需要物件B的時候,IOC容器會主動建立一個物件B注入到物件A需要的地方。
  • 通過前後的對比,我們不難看出來:物件A獲得依賴物件B的過程,由主動行爲變爲了被動行爲,控制權顛倒過來了,這就是「控制反轉」這個名稱的由來。

IOC的別名:依賴注入(DI)

  • 既然IOC是控制反轉,那麼到底是「哪些方面的控制被反轉了呢?」,經過詳細地分析和論證後,他得出了答案:「獲得依賴物件的過程被反轉了」。控制被反轉之後,獲得依賴物件的過程由自身管理變爲了由IOC容器主動注入。
  • 於是,他給「控制反轉」取了一個更合適的名字叫做「依賴注入(Dependency Injection)」。他的這個答案,實際上給出了實現IOC的方法:注入所謂依賴注入,就是由IOC容器在執行期間,動態地將某種依賴關係注入到物件之中

IOC爲我們帶來了什麼好處?

  • 無論兩者中的任何一方出現什麼的問題,都不會影響另一方的執行。這種特性體現在軟體工程中,就是可維護性比較好,非常便於進行單元測試,便於偵錯程式和診斷故障。程式碼中的每一個Class都可以單獨測試,彼此之間互不影響,只要保證自身的功能無誤即可,這就是元件之間低耦合或者無耦合帶來的好處。
  • 每個開發團隊的成員都只需要關心實現自身的業務邏輯,完全不用去關心其它的人工作進展,因爲你的任務跟別人沒有任何關係,你的任務可以單獨測試,你的任務也不用依賴於別人的元件,再也不用扯不清責任了。所以,在一個大中型專案中,團隊成員分工明確、責任明晰,很容易將一個大的任務劃分爲細小的任務,開發效率和產品品質必將得到大幅度的提高
  • 可複用性我們可以把具有普遍性的常用元件獨立出來,反覆 反復利用到專案中的其它部分,或者是其它專案,當然這也是物件導向的基本特徵。顯然,IOC不僅更好地貫徹了這個原則,提高了模組的可複用性。符合介面標準的實現,都可以插接到支援此標準的模組中。
  • IOC生成物件的方式轉爲外接方式,也就是把物件生成放在組態檔裡進行定義,這樣,當我們更換一個實現子類將會變得很簡單,只要修改組態檔就可以了,完全具有熱插撥的特性

IOC容器的技術剖析

  • IOC中最基本的技術就是「反射(Reflection)」程式設計,有關反射的概念和用法,大家應該都很清楚,通俗來講就是根據給出的類名(字串方式)來動態地生成物件。 反射技術其實很早就出現了,但一直被忽略,沒有被進一步的利用。當時的反射程式設計方式相對於正常的物件生成方式要慢至少得10倍。現在的反射技術經過改良優化,已經非常成熟,反射方式生成物件和通常物件生成方式,速度已經相差不大了,大約爲1-2倍的差距。

  • 我們可以把IOC容器的工作模式看做是工廠模式的昇華,可以把IOC容器看作是一個工廠,這個工廠裡要生產的物件都在組態檔中給出定義,然後利用程式語言的的反射程式設計,根據組態檔中給出的類名生成相應的物件。從實現來看,IOC是把以前在工廠方法裡寫死的物件生成程式碼,改變爲由組態檔來定義,也就是把工廠和物件生成這兩者獨立分隔開來,目的就是提高靈活性和可維護性。

使用IOC框架應該注意什麼

使用IOC框架產品能夠給我們的開發過程帶來很大的好處,但是也要充分認識引入IOC框架的缺點,做到心中有數,杜絕濫用框架。
第一、**軟件系統中由於引入了第三方IOC容器,生成物件的步驟變得有些複雜,本來是兩者之間的事情,又憑空多出一道手續,所以,我們在剛開始使用IOC框架的時候,會感覺系統變得不太直觀。**所以,引入了一個全新的框架,就會增加團隊成員學習和認識的培訓成本,並且在以後的執行維護中,還得讓新加入者具備同樣的知識體系。
第二、**由於IOC容器生成物件是通過反射方式,在執行效率上有一定的損耗。**如果你要追求執行效率的話,就必須對此進行權衡。
第三、具體到IOC框架產品(比如:Spring)來講,需要進行大量的配製工作,比較繁瑣,對於一些小的專案而言,客觀上也可能加大一些工作成本
第四、IOC框架產品本身的成熟度需要進行評估,如果引入一個不成熟的IOC框架產品,那麼會影響到整個專案,所以這也是一個隱性的風險