對於Spring中AOP,DI,IoC概念的理解

天天不是小可愛發表於2019-07-11

IOC


IoC(inversion of Control),控制反轉。就好像敏捷開發和SCRUM一樣,不是什麼技術,而是一種方法論,一種工程化的思想。使用IoC的思想意味著你將設計好的物件交給容器控制,而不是傳統的在你的物件內部直接控制。

為什麼要控制反轉呢,誰在控制誰呢,反轉了什麼東西呢?這篇筆記聊的就是這些東西

  • 誰在控制誰? 一般來講,我們直接new一個物件,是我們執行的這個程式去主動的建立依賴物件;但是IoC時會有一個IoC容器來負責這些物件的建立。這個時候IoC容器控制了物件,控制了外部資源獲取。
  • 反轉了什麼呢?在傳統的程式裡面,我們在物件中主動控制去直接獲取依賴物件,而現在,這個過程反了過來。

依賴(在A類裡面建立了B類的例項,這樣A依賴於B)

舉例說明下?

在Github上面看到了一段很有意思的虛擬碼,我感覺很能解釋IoC的關係,於是就摘抄到這裡面來

在生活中,和一個女孩子認識有三種方法

  1. 青梅竹馬

    public class Girl{
       void Kiss(){
          Boy RightPerson = new Boy();
       }
    }

    這個RightPerson最大的缺點就是沒辦法更換(...),在Boy的整個生命週期裡面他都會存在,如果Girl想換一個boy kiss呢,就不是很好了(...)

  2. 相親平臺

    public class Girl{
       void Kiss(){
          Boy Boy = BoyFactory.createBoy();
       }
    }

    這個Boy是不是RightPerson就不知道了,但是不滿意就換。但是我們現在有了一個Boy Factory,這很煩,有外人/平臺介入了日常生活,它以單例模式或者是存在於全域性。

  3. 值得信賴的人安排,只需要守株待兔

    public class Girl{
       void kiss(Boy boy){
           boy.kiss();
       }
    }

    你傳什麼給我,我就和什麼Kiss(表達有點不大合適,但是也想不出什麼好詞了),至少這種方式Girl和Boy不用忙活了。

這就是IoC的基本思想,將物件的建立和提取到外部,由外部容器提供所需要的元件。

為什麼要使用IoC呢

說實話,”高內聚,低耦合“這句話我都聽到吐了。每個上過軟體工程導論課的同學都能跟你侃侃而談五分鐘。那接著往下問”什麼是內聚,什麼是耦合“”為什麼要倡導鬆耦合的設計,這跟物件導向設計法則又有什麼關係呢?“

有了IoC容器後,把建立和查詢依賴物件的控制權交給了容器,由容器進行注入組合物件,所以物件與物件之間的耦合是鬆散的,這樣也方便測試,利於功能複用,更重要的是使得程式的整個體系結構變得非常靈活。

IoC相當於是將應用程式賦予給了一箇中心,IoC容器。

DI


都提到IoC了,怎麼能少得了DI(Dependency Injection ),注入依賴或者依賴注入?anyway,隨便你。元件之間的依賴關係由容器在執行過程中規定。具象化一點,各個元件的依賴關係是由容器來注入的。開發者依賴這個機制,只需要通過配置指定資源,完成業務邏輯即可,不用關心具體的資源來自何方,由誰實現(依然是物件導向的思想)

 那麼,你說的這個DI和IoC,他們有區別嗎?

有區別,但是其實DI和IoC說的是一個東西,因為IoC這個東西說的模模糊糊,Martin Fowler(XP的提出者之一,敏捷方法的創始人)在2004提出了DI的概念,“依賴注入”明確描述了“被注入物件依賴IoC容器配置依賴物件”。

Martin Fowler 的原文是這樣的,在inversion of Control這一節裡面,他提到

As a result I think we need a more specific name for this pattern. Inversion of Control is too generic a term, and thus people find it confusing. As a result with a lot of discussion with various IoC advocates we settled on the name Dependency Injection.

IoC是我們想要做的事情,每個框架都說自己IoC,DI是我們採取的手段

我摘了一段知乎的回答,問題的連結貼在下面,有些回答舉了一些具體的例子,很有利於理解

ioc的思想最核心的地方在於,資源不由使用資源的雙方管理,而由不使用資源的第三方管理,這可以帶來很多好處。

第一,資源集中管理,實現資源的可配置和易管理。

第二,降低了使用資源雙方的依賴程度,也就是我們說的耦合度。

AOP(Aspect-Oriented Programming)


我們都知道Spring的AOP是這個框架的重要組成部分 ,那AOP,面向切面程式設計又是在做什麼呢?
在物件導向的思想裡面(Object-Oriented Programing)有三大法寶,”封裝,繼承,多型“,用這三大法寶建立了物件的層次,但是它是一個縱向的結構,有比較明確的上下級關係,但是在平行的層次中發揮不出太大的作用。

所以我們又需要一種橫向的結構來定義這些平行的關係,以日誌記錄為例,記錄日誌一般要在操作完畢之後,用OOP的思想,那我就要去專案的每個運算元據庫的方法的裡面去加上儲存日誌,這會導致程式碼重複,模組的重用會因此受到影響。

如果使用AOP,只需要自定義一個方法,在spring配置檔案中將該方法配置好,當每次呼叫完原先的save方法時,都會去執行你寫的儲存日誌方法。

它將程式中的交叉業務邏輯(日誌,事務等),封裝成一個切面,然後注入到目標物件(具體業務邏輯)中去。

參考

  1. 《Spring實戰》

  2. Spring IoC有什麼好處呢 https://www.zhihu.com/question/23277575/answer/134413451 (這裡面有一些回答很有參考價值,仔細看看發現自己以前的理解還是有問題)

  3. Inversion of Control Containers and the Dependency Injection pattern https://martinfowler.com/articles/injection.html

  4. ioc https://github.com/biezhi/java-bible/tree/master/ioc

相關文章