[09] 環繞通知和切入表達式

一、前置/後置/返回/異常/通知

Spring在執行AOP時實際上流程以下:
  • 首先執行前置通知
  • 而後執行目標組件,若是過程當中出現異常,則執行異常通知
  • 而後執行後置通知
  • 最後判斷若是目標組件正常執行,則再執行返回通知


  • before,前置通知,組件參數有JoinPoint
  • after,後置通知,組件參數有JoinPoint
  • after-returning,返回通知,組件參數除了JoinPoint,還有Object做爲返回值,需在配置文件中定義
  • after-throwing,異常通知,組件參數除了JoinPoint,還有Throwable,會在目標程序拋出異常以後獲取,也須要在配置文件中定義

二、環繞通知

經過環繞通知,能夠實現前置通知、後置通知等等能夠實現的功能。在類型爲環繞通知的切面程序函數中,參數則再也不是JoinPoint,而是ProceddingJoinPoint,它是JoinPoint的子類,進行了擴展,提供了proceed()函數,該函數的做用是調用目標組件,並返回目標組件返回的值。
public void doAround(ProceedingJoinPoint point) { 
    System.out.println("目標組件運行的前置通知");
    try {
        Object obj = point.proceed();
        System.out.println("目標組件的返回通知");
    } catch (Throwable throwable) {
        System.out.println("執行異常處理程序");
    }
    System.out.println("最終執行程序");
}
<aop:aspect ref="section">
    <!-- 通知爲環繞,method爲方法,pointcut-ref做用在哪些切入點 -->
    <aop:around method="doAround" pointcut-ref="targetPointCut"/>
</aop:aspect>

三、切入表達式

切入表達式用於聲明Spring容器中哪些組件的函數是目標函數,也就是切面程序要做用到哪些組件的哪些函數上。

經常使用的切入表達式分爲:
  • 按類匹配
    • 匹配的Java類中所有函數做爲目標函數,使用within關鍵字
  • 按函數匹配
    • 匹配的函數做爲目標函數,使用execution關鍵字
  • 按bean的id匹配
    • 匹配的bean中所有函數做爲目標函數,使用bean關鍵字

3.1 按類匹配

匹配到指定類 .Xxx
<aop:pointcut id="targetPoint" expression="within(dulk.learn.aop.Target)" />

匹配到包下的類 .*
<aop:pointcut id="targetPoint" expression="within(dulk.learn.aop.*)" />

匹配到包下及子包下的類 ..*
<aop:pointcut id="targetPoint" expression="with(dulk..*)" />

3.2 按函數匹配

表達式的完整寫法(以以前的demo爲示例):
execution(String dulk.learn.aop.Target.print(String))
如上:
  • 首個String - 表示返回類型
  • dulk.learn.aop - 表示類的路徑
  • Target - 表示類名
  • print - 表示函數名
  • 最後個String - 表示參數類型,用","分開


任意返回類型
execution(* dulk.learn.aop.Target.print(String))

任意返回類型下指定包下任意類
execution(* dulk.learn.aop.*.print(String))

任意返回類型下指定包下任意類任意函數
execution(* dulk.learn.aop.*.*(String))

任意返回類型下指定包或子包下任意類任意函數任意參數
execution(* dulk..*.*(..))


3.3 按bean的id匹配

表達式的關鍵字爲bean,以後括號中的內容則爲對應bean組件的id。

根據bean組件名稱匹配:
<aop:pointcut id="targetPoint" expression="bean(target)" />

根據bean組件名稱(含通配符)匹配,若有target1,target2等bean組件,則能夠統一使用target*表示:
<aop:pointcut id="targetPoint" expression="bean(target*)" />
相關文章
相關標籤/搜索