暑期自學 Day 19 | Spring (五)

Borris發表於2020-07-12

AOP 面向切面程式設計

透過預編譯方式和執行期動態代理實現程式功能的統一維護的一種技術。

  • 作用:在程式執行期間,不修改原始碼對已有方法進行增強(動態代理)
  • 優勢:減少重複程式碼,提高開放效率,方便維護
  • 實現:利用動態代理(詳見____),在spring中,可以透過配置方式實現動態代理。

spring AOP的選擇:看是否使用介面,選擇使用基於介面還是基於子類的動態代理。(基於子類的動態代理也可以用於介面中。)

Spring 基於 xml 的 AOP 配置

就是把通知bean交給spring配置。比如說為每個方法建立資料庫操作的事務時,需要用到開啟,提交,回滾,釋放事務的操作。如果每個方法都寫這些操作過程,會造成程式碼的重複。利用AOP配置,可以有效減少這部分的程式碼量,提高程式設計效率,也使程式碼更容易維護。

操作步驟:

在bean.xml檔案中

  1. 使用<aop:config>標籤標示開始配置
  2. 使用<aop:aspect>表示配置的切面
    id:切面的唯一標示
    ref: 指定通知類bean的id
  3. aop:aspect標籤內部使用對應標籤來配置通知的型別
    通知型別分為五種,前置(before),後置(afterReturning),異常(afterThrowing),最終(after),環繞(around)
    • aop:xxx:
      • method屬性,用於指定哪個方法屬於該類通知;
        • pointcut:用於指定使用該通知的切入點方法
        • pointcut-ref:用於引入配置好的切入點表示式
  4. 配置切入點表示式:
    • <aop:pointcut id="pt1" expression="execution(* service.impl.*.*(..))"/>
通知型別
  • 前置,後置,異常,最終顧名思義

  • 環繞通知 - spring框架為我們提供的一種可以在程式碼中手動控制增強方法何時執行的方式

    • 問題:當我們配置了環繞通知之後,切入點方法沒有執行,而通知方法執行了。
    • 分析:透過對比動態代理中的環繞通知程式碼,發現動態代理的環繞通知有明確的切入點方法呼叫,而我們的程式碼中沒有。
    • 解決:Spring框架為我們提供了一個介面:ProceedingJoinPoint。該介面有一個方法proceed(),此方法就相當於明確呼叫切入點方法。該介面可以作為環繞通知的方法引數,在程式執行時,spring框架會為我們提供該介面的實現類供我們使用。
切入點表示式的寫法
  • 標準寫法

    • 關鍵字:execution(表示式)
    • 表示式:
      • 訪問修飾符 返回值 包名.包名 包名.包名 包名.包名 包名.包名…類名.方法名(引數列表)
      • public void service.impl.AccountServiceImpl.saveAccount()
  • 萬用字元寫法

    • 訪問修飾符可省略;

    • 返回值可使用萬用字元,表示任意返回值;

    • 包名使用萬用字元, 有幾級包寫幾個*.,可以使用..表示當前包和子包

    • 方法名和類名都可以使用*通配

    • 引數列表可以寫引數型別:基本型直接寫名稱,引用型寫包名.類名

    • 可以用萬用字元表示任意型別,但是必須有引數

    • 用..表示有無引數均可

    • 全通配寫法

      • * *..*.*(..)
    • 實際開發中通常寫法最好要切到業務層實現類下的所有方法

      • * service.impl.*.*(..)

AOP基於註解的配置

所有的基於xml的配置均可以改為透過註解配置。

配置步驟:

  • 首先需要宣告我們在透過註解方法配置AOP
    • @EnableAspectAutoProxy 或者 <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
  • IOC容器的基於註解配置詳見之前的筆記
  • 在需要作為切面的類前加@Aspect註解
  • 在切面類中宣告@Pointcut切入點表示式
    • @Pointcut("execution(* spring.selflearning.service.impl.*.*(..))") private void pt1(){};
  • 為每個方法配置相應的通知類註解,並引入切入點表示式
    • @Around("pt1()")

說明

透過註解配置AOP,後置通知會晚於最終通知出現,這個問題可以透過配置環繞通知來解決。

程式碼連結

基於子類的動態代理
AOP配置
AOP通知型別

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章