Spring之AOP

Aop為什么會出現(xiàn)呢?本質(zhì)上來說,是為了實現(xiàn)單一職責(zé)原則的思想,我們在做一個save操作的時候,往往需要先開啟事務(wù),如果成功提交事務(wù),失敗了回滾事務(wù),最后還得關(guān)閉事務(wù)。最后說的這些事情其實在所有的業(yè)務(wù)邏輯中都是需要的,所以說都是些重復(fù)的操作,顯然這樣很不"程序猿"。于是為了對業(yè)務(wù)進行增強,加入一些必要的附屬操作,AOP就這么誕生出來了

其實有可能你會發(fā)現(xiàn),AOP好像和代理模式非常的相似,沒錯,AOP就是用代理模式進行實現(xiàn)的。

代理模式可以分為兩種

  1. 靜態(tài)代理

    在編譯期間就已經(jīng)存在一個代理類

  2. 動態(tài)代理

    不存在代理類的字節(jié)碼文件,是通過反射動態(tài)生成的,是在運行期間,才確定關(guān)系的。

    1.Java動態(tài)代理(真實對象必須存在接口)

    • 原理:動態(tài)代理其實本質(zhì)上也是靜態(tài)代理的實現(xiàn)方法,只不過代理類不是由我們提供的,而是通過程序生成一個字節(jié)碼文件,然后加載進虛擬機中。是通過實現(xiàn)接口的方式
    • 使用的是reflect包下的Proxy和InvocationHandler 接口進行代理的
    • 動態(tài)代理的最小單位是類,也就是說會為該類的所有public方法進行增強。(但是可以通過判斷方法的一些特性,決定是否放行)

    2.CGlib動態(tài)代理

    • 原理: 通過繼承了實現(xiàn)類的方式,對方法進行增強
    • 被代理的類必須得是非final的

    性能方面: Javassit > CGlib > JDK

Tips: AOP 使用了一種攔截器(Interceptor)的思想,相對于Filter只能應(yīng)用于web領(lǐng)域,interceptor可以應(yīng)用于各個領(lǐng)域,應(yīng)用范圍更過

AOP之關(guān)鍵字

  1. JoinPoint 連接點,連接的是需要被增強的方法,強調(diào)的是去哪里做增強
  2. PointCut 切入點, 是JoinPoint的一個集合,強調(diào)的是取哪些地方做增強。
  3. Advice 增強,在方法執(zhí)行的某一個時機,應(yīng)該如何做增強。增強的類型共分為5種:
    1. 前置增強
    2. 后置增強
    3. 異常增強
    4. 最終增強
    5. 環(huán)繞增強
  4. Target 目標(biāo)對象
  5. Aspect 切面 = JoinPoint + Advice
  6. weaving 植入,把advise加到target上,然后創(chuàng)建代理過程的對象

PointCut語法

參考spring官網(wǎng)

AspectJ與動態(tài)代理

他倆最大的差別就在于動態(tài)代理是在運行的時候生成相應(yīng)的class文件,而AspectJ則不是,它是通過編譯成字節(jié)碼文件的時候就被織入了字節(jié)碼文件中,所以AspectJ也可以切私有方法,而動態(tài)代理卻做不到。

AOP的配置使用

xml方式

在xml文件中加入了aop的命名空間后,寫入以下代碼:

<aop:config>
    <aop:aspect ref="使用哪個類做增強">
    <aop:pointcut id="pointcutA" expression="pointcut的execution表達式"/> <!--對哪些方法做增強-->
    <aop:before method="aop:aspect標(biāo)簽中ref屬性的某個方法" pointcut-ref="pointcutA"/><!--調(diào)用前增強-->
    <aop:after-returning  method="aop:aspect標(biāo)簽中ref屬性的某個方法" pointcut-ref="pointcutA" /><!--對返回后增強-->
    <aop:after-throwing method="aop:aspect標(biāo)簽中ref屬性的某個方法" pointcut-ref="pointcutA" throwing =""/> <!--出現(xiàn)異常后增強-->
    <aop:after-throwing method="aop:aspect標(biāo)簽中ref屬性的某個方法" pointcut-ref="pointcutA" /> <!--最終增強,無論有沒有異常,適用于釋放資源-->
    <aop:around />
  </aop:aspect>  
</aop:config>
注解方式

與上面的xml方式,十分類似也可以一一對應(yīng)上。

  • 首先需要在切面類上面使用@aspect
  • 如果是前置的增強使用@Before
  • 如果是返回后置的使用@AfterReturning
  • 如果是異常后置的使用@AfterThrowing
  • 如果是最后的返回,使用@After
  • 如果是全方位的進行定制化,使用@Around

對應(yīng)的這些注解擁有的屬性,也是和xml中擁有的屬性幾乎相同。

Tips:經(jīng)過我的實驗證明@After會在@AfterReturning 和@AfterThrowing之前執(zhí)行的

那么問題來了,我們現(xiàn)在想要獲取被切的對象的相關(guān)信息應(yīng)該如何做呢?

1.如果是異常增強:我們可以通過配置配置throwing參數(shù),拿到被拋出的異常的對象。

2.除了異常增強和環(huán)繞增強之外,可以通過JoinPoint作為第一個參數(shù)獲取到相關(guān)的信息,包括被切的對象,方法參數(shù)等等

3.如果是應(yīng)用于環(huán)繞增強那么,使用ProcessingJoinPoint,它其實是JoinPoint的一個子類,不僅可以獲取相關(guān)的信息,還可以調(diào)用真實被環(huán)繞的方法。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • AOP介紹 在軟件業(yè),AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通...
    沈默的頭號狗腿閱讀 463評論 0 0
  • 六、 通知參數(shù) 前邊幾篇文章已經(jīng)介紹了聲明通知,但如果想獲取被被通知方法參數(shù)并傳遞給通知方法,該如何實現(xiàn)呢?接下來...
    聶叼叼閱讀 849評論 0 0
  • spring的面向切面編程,即aop編程是有3種作用的: - 日志記錄 - 安全驗證 - 數(shù)據(jù)庫事務(wù)管理 這里簡單...
    安徒生閱讀 5,025評論 0 0
  • 文章大綱 一、AOP介紹二、Spring的AOP實戰(zhàn)三、AOP常用標(biāo)簽四、項目源碼及參考資料下載五、參考文章 一、...
    故事愛人c閱讀 525評論 0 0
  • 王尚義臉上的皺紋紋絲不動,如同雕刻。他耐心等王景元吼完了,煙袋鍋子收起來,語氣和緩,不急不躁,卻沒什么商量的余地,...
    憑欄仙后閱讀 563評論 0 6

友情鏈接更多精彩內(nèi)容