AOP的相關理論介紹


1、AOP的介紹

AOP為Aspect Oriented Programming的縮寫,即面向切面編程(也叫面向方面),是一種可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術。

編程思想
描述
面向對象編程(OOP) 簡化代碼:把重復代碼縱向抽取到父類,OOP的三大特征繼承、封裝、多態,它主要是為了實現編程的重用性、靈活性和擴展性,強調的是類之間的層次關系
面向接口編程 解耦:不同組件之間解耦,即使一個組件改變了也不會影響其它的
面向切面編程(AOP) 簡化代碼:把方法中的重復代碼橫向抽取到切面中,它是對方法的增強

2、為什么學習AOP

下面來分析一下面向對象編程(OOP)的局限性。

例如這里有兩個類,兩個類的方法1中的內容是重復的,而方法2是不重復的,此時我們就可以將方法1中的代碼抽取出來放入父類中,這是典型的面向對象編程思想。

image

但是如果兩個類的方法1中的內容只有部分是相同的,但是你又想將相同的方法抽取出來,這時再使用面向對象編程就無法實現了,因為相同的代碼是存在於方法的內部,此時就可以使用AOP來實現了。

image


為了更好的理解OOP和AOP,下面簡單舉例說明:

①、定義一個簡單的計算器類,內部功能為簡單的加減乘除運算。

image

②、此時增加功能,給每個運算操作的前后都打印一下日志。

image

這樣附加功能后,代碼存在明顯的問題:

  • 代碼會變得非常臃腫
  • 核心邏輯的代碼和非核心邏輯的代碼混雜在一起,不利於開發和維護
  • 將來不管是核心代碼還是非核心代碼想要升級或調試bug,都非常不便

而且這種情況也不能將相同的代碼抽取出來放在父類中,但是可以用到AOP思想來解決。

③、使用AOP思想來解決上述問題,將不同的方法中相同的邏輯代碼橫向抽取出來,在使用時通過代理類織入到指定位置就能夠完成特定的功能。

image

image


OOP與AOP對比

①相同點

  • 都可以簡化代碼

②不同點

  • 面向對象:縱向抽取
  • 面向切面:橫向抽取

AOP的總結:把『圍繞』着目標代碼的固定代碼『抽取』出來,『封裝』成固定的解決方案,哪里需要,哪里

3、AOP的應用場景

  • 日志記錄
  • 事務處理
  • 緩存處理
  • 權限校驗
  • 性能統計
  • 計數
  • ......

4、AOP的實現原理(理論)

AOP的實現原理:基於動態代理完成,這個幾乎人盡皆知。

動態代理是二十三種設計模式中的一種,屬於結構型模式。它的作用就是通過提供一個代理類,讓我們在調用目標方法的時候,不再是直接對目標方法進行調用,而是通過代理類間接調用。讓不屬於目標方法核心邏輯的代碼從目標方法中剝離出來。調用目標方法時先調用代理對象的方法,減少對目標方法的調用和打擾。

動態代理有兩種實現方式:

  • JDK動態代理:需要被代理的目標類必須實現相應接口。利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理。
  • CGlib動態代理:通過繼承被代理的目標類實現代理,所以不需要目標類實現接口。利用ASM(開源的Java字節碼編輯庫,操作字節碼)開源包,將代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。

二者區別:JDK代理只能對實現接口的類生成代理;CGlib是針對類實現代理,對指定的類生成一個子類,並覆蓋其中的方法,這種通過繼承類的實現方式,不能代理final修飾的類。

細節補充(了解就好):如果AOP是通過JDK動態代理實現的,那么接口的實現類在應用了切面后,真正放在IOC容器中的是代理類的對象,目標類並沒有被放到IOC容器中,所以根據目標類的類型從IOC容器中是找不到的,例如:ac.getBean(UserServiceImpl.class);


①、不使用代理與使用代理

image image

②、生活中的代理

  • 廣告商找大明星拍廣告需要經過經紀人
  • 合作伙伴找大老板談合作要約見面時間需要經過秘書
  • 房產中介是買賣雙方的代理

③、相關術語

  • 代理:將非核心邏輯剝離出來以后,封裝這些非核心邏輯的類、對象、方法。
  • 目標:被代理“套用”了非核心邏輯代碼的類、對象、方法。

④、AOP中使用的是JDK代理還是CGLib代理

image

  • 如果在AOP中被代理的是一個接口的實現類,那么AOP中使用就是JDK動態代理
  • 如果在AOP中被代理的類是一個普通類,那么AOP中使用就是CGlib動態代理

5、AOP的相關術語

注意:AOP相關的術語不是唯一的,其實官方文檔對這些術語的介紹也不是很清晰,它本身是不存在的,都是一些概念相關的東西,簡單了解這些術語是什么意思就好。

AOP相關術語的整體截圖:

image


術語
描述
切面(Aspect) 切面由切入點(Pointcut)和通知(Advice)組成,它既包括了橫切邏輯的定義、也包括了連接點的定義,所以通常來說它是一個類,就是被@Aspect注解注上的類。
通知/增強(Advice) AOP在特定的切入點上執行的增強處理,也就是具體的橫切邏輯。簡單來說就定義了是干什么的,具體是在哪干。Spring AOP提供了5種Advice類型給我們:前置、后置、返回、異常、環繞,下面會詳細介紹
連接點(JointPoint) 目標類中每個成員方法都可以稱之為連接點,一個連接點總是代表一個方法執行。可以這么理解:把方法排成一排,每一個橫切位置看成x軸方向,把方法從上到下執行的順序看成y軸,x軸和y軸的交叉點就是連接點。
切入點(Pointcut) 定位連接點的方式。上面也說了,每個方法都可以稱之為連接點,我們具體定位到某一個方法就稱為切入點,在程序中主要體現為書寫切入點表達式。切點分為execution方式和annotation方式。前者可以用路徑表達式指定哪些類織入切面,后者可以指定被哪些注解修飾的代碼織入切面。
織入(Weaving) 就是通過動態代理,將通知添加到目標類的具體連接點上的過程。
目標(Target) 表示被代理的目標對象。
代理(Proxy) 表示向目標對象應用通知之后創建的代理對象。

通知/增強(Advice)中提供的五中類型(非常重要):

通知類型 描述
前置通知(@Before) 在我們執行目標方法之前運行。
返回通知(@AfterReturning) 在我們的目標方法正常返回值后運行。
異常通知(@AfterThrowing) 在我們的目標方法出現異常后運行。
后置通知(@After) 在我們目標方法運行結束之后 ,不管有沒有異常。
環繞通知(@Around) 包括上面四種通知對應的所有位置。

為了方便理解上面的通知類型,下面結合try-catch-finally模型舉例:

image


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM