深刻理解Spring的兩大特徵(IOC和AOP)

衆所周知,Spring的核心特性就是IOC和AOP,IOC(Inversion of Control),即「控制反轉」;AOP(Aspect-OrientedProgramming),即「面向切面編程」。參考書《Spring In Action》,下面分享一下我對這兩大特性的我的理解。spring

IOC:IOC,另一種說法叫DI(Dependency Injection),即依賴注入。它並非一種技術實現,而是一種設計思想。在任何一個有實際開發意義的程序項目中,咱們會使用不少類來描述它們特有的功能,而且經過類與類之間的相互協做來完成特定的業務邏輯。這個時候,每一個類都須要負責管理與本身有交互的類的引用和依賴,代碼將會變的異常難以維護和極度的高耦合。而IOC的出現正是用來解決這個問題,咱們經過IOC將這些相互依賴對象的建立、協調工做交給Spring容器去處理,每一個對象只須要關注其自身的業務邏輯關係就能夠了。在這樣的角度上來看,得到依賴的對象的方式,進行了反轉,變成了由spring容器控制對象如何獲取外部資源(包括其餘對象和文件資料等等)。數據庫

舉例:某一天,你生病了,可是你不清楚本身到底得了什麼病,你只知道本身頭疼,咳嗽,全身無力。這個時候你決定去藥店買藥,藥店有不少種藥,僅僅是治療頭疼就有好幾十種,還有西藥中藥等區別。而後你本身看了看說明書,選擇了一盒你本身以爲最能治療本身病症的藥,付錢吃藥,期待能夠早點好起來。 
可是這個過程,對於一個病人來講,太辛苦了。頭疼,咳嗽,全身無力,還要一個個的看藥品說明書,一個個的比較哪一個藥比較好,簡直是太累了。這個時候,你決定直接去醫院看醫生。 
醫生給你作了檢查,知道你的病症是什麼,有什麼緣由引發的;同時醫生很是瞭解有哪些藥能治療你的病痛,而且能根據你的自身狀況進行篩選。只須要短短的十幾分鍾,你就能拿到對症下藥的藥品,即省時又省力。編程

在上面這個例子中,IOC起到的就是醫生的做用,它收集你的需求要求,而且對症下藥,直接把藥開給你。你就是對象,藥品就是你所須要的外部資源。經過醫生,你不用再去找藥品,而是經過醫生把藥品開給你。這就是整個IOC的精髓所在。安全

AOP:面向切面編程,每每被定義爲促使軟件系統實現關注點的分離的技術。系統是由許多不一樣的組件所組成的,每個組件各負責一塊特定功能。除了實現自身核心功能以外,這些組件還常常承擔着額外的職責。例如日誌、事務管理和安全這樣的核心服務常常融入到自身具備核心業務邏輯的組件中去。這些系統服務常常被稱爲橫切關注點,由於它們會跨越系統的多個組件。設計

AOP的概念很差像IOC同樣實例化舉例,如今咱們以一個系統中的具體實現來說講AOP具體是個什麼技術。代理

咱們以系統中經常使用到的事務管控舉例子。在系統操做數據庫的過程當中,不可避免地要考慮到事務相關的內容。若是在每個方法中都新建一個事務管理器,那麼無疑是對代碼嚴重的耦合和侵入。爲了簡化咱們的開發過程(實際上spring所作的一切實現都是爲了簡化開發過程),須要把事務相關的代碼抽成出來作爲一個獨立的模塊。經過AOP,確認每個操做數據庫方法爲一個鏈接點,這些鏈接點組成了一個切面。當程序運行到其中某個一個切點時,咱們將事務管理模塊順勢織入對象中,經過通知功能,完成整個事務管控的實現。這樣一來,全部的操做數據庫的方法中不須要再單獨關心事務管理的內容,只須要關注自身的業務代碼的實現便可。全部的事務管控相關的內容都經過AOP的方式進行了實現。簡化了代碼的內容,將目標對象複雜的內容進行解耦,分離業務邏輯與橫切關注點。日誌

下面介紹一下AOP相關的術語:對象

  • 通知: 通知定義了切面是什麼以及什麼時候使用的概念。Spring 切面能夠應用5種類型的通知:生命週期

    • 前置通知(Before):在目標方法被調用以前調用通知功能。
    • 後置通知(After):在目標方法完成以後調用通知,此時不會關心方法的輸出是什麼。
    • 返回通知(After-returning):在目標方法成功執行以後調用通知。
    • 異常通知(After-throwing):在目標方法拋出異常後調用通知。
    • 環繞通知(Around):通知包裹了被通知的方法,在被通知的方法調用以前和調用以後執行自定義的行爲。
  • 鏈接點:是在應用執行過程當中可以插入切面的一個點。事務

  • 切點: 切點定義了切面在何處要織入的一個或者多個鏈接點。
  • 切面:是通知和切點的結合。通知和切點共同定義了切面的所有內容。
  • 引入:引入容許咱們向現有類添加新方法或屬性。
  • 織入:是把切面應用到目標對象,並建立新的代理對象的過程。切面在指定的鏈接點被織入到目標對象中。在目標對象的生命週期中有多個點能夠進行織入: 
    • 編譯期: 在目標類編譯時,切面被織入。這種方式須要特殊的編譯器。AspectJ的織入編譯器就是以這種方式織入切面的。
    • 類加載期:切面在目標加載到JVM時被織入。這種方式須要特殊的類加載器(class loader)它能夠在目標類被引入應用以前加強該目標類的字節碼。
    • 運行期: 切面在應用運行到某個時刻時被織入。通常狀況下,在織入切面時,AOP容器會爲目標對象動態地建立一個代理對象。SpringAOP就是以這種方式織入切面的。
相關文章
相關標籤/搜索