1. 程式人生 > >Spring Boot (Web 篇):配置 AOP 切面

Spring Boot (Web 篇):配置 AOP 切面

目錄

AOP 簡介

AOP相關概念

AOP相關注解

編寫AOP

在pom.xml加入相關依賴

編寫切面類

頁面訪問(專案啟動)

JoinPoint詳解

關於多個切面的執行順序

總結

原始碼下載


AOP 簡介

AOP相關概念

  • Target(目標物件):需要被代理增強的物件
  • Proxy(代理物件):目標物件被AOP 織入 增強/通知後,產生的物件.
  • Joinpoint(連線點):指那些被攔截到的點.在Spring中,這些點指方法(因為Spring只支援方法型別的連線點).
  • Pointcut(切入點):指需要(配置)被增強的Joinpoint.
  • Advice(通知/增強):指攔截到Joinpoint後要做的操作.通知分為前置通知/後置通知/異常通知/最終通知/環繞通知等.
  • Aspect(切面):切入點和通知的結合。
  • Weaving(織入):指把增強/通知應用到目標物件來建立代理物件的過程(Spring採用動態代理織入,AspectJ採用編譯期織入和類裝載期織入)
  • Introduction(引入增強):一種特殊通知,在不修改類程式碼的前提下,可以在執行期為類動態地新增一些Method/Field(不常用)

AOP相關注解

  • @Aspect註解將一個java類定義為切面類
  • @Pointcut定義一個切入點,可以是一個規則表示式
  • @Before在切入點開始處切入內容
  • @After在切入點結尾處切入內容
  • @AfterReturning在切入點return內容之後切入內容(可以用來對處理返回值做一些加工處理)
  • @AfterThrowing用來處理當切入內容部分丟擲異常之後的處理邏輯
  • @Around在切入點前後切入內容,並自己控制何時執行切入點自身的內容

編寫AOP

在pom.xml加入相關依賴

編寫切面類

使用 @Component,@Aspect 標記到切面類上:

頁面訪問(專案啟動)

頁面隨便請求某個Controller

JoinPoint詳解

AspectJ使用org.aspectj.lang.JoinPoint介面表示目標類連線點物件,如果是環繞增強時,使用org.aspectj.lang.ProceedingJoinPoint表示連線點物件,該類是JoinPoint的子介面。任何一個增強方法都可以通過將第一個入參宣告為JoinPoint訪問到連線點上下文的資訊。我們先來了解一下這兩個介面的主要方法:

1)JoinPoint

  • java.lang.Object[] getArgs():獲取連線點方法執行時的入參列表;
  • Signature getSignature() :獲取連線點的方法簽名物件;
  • java.lang.Object getTarget() :獲取連線點所在的目標物件;
  • java.lang.Object getThis() :獲取代理物件本身;

2)ProceedingJoinPoint

ProceedingJoinPoint繼承JoinPoint子介面,它新增了兩個用於執行連線點方法的方法: 
- java.lang.Object proceed() throws java.lang.Throwable:通過反射執行目標物件的連線點處的方法; 
- java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通過反射執行目標物件連線點處的方法,不過使用新的入參替換原來的入參。
常用的幾個:

//獲取目標方法所在類名稱
String className = joinPoint.getSignature().getDeclaringTypeName()

//獲取目標方法名稱
String methodName = joinPoint.getSignature().getName();

//獲取目標方法完整名稱
String fullMethodName = className + "." + methodName;

//獲取目標方法引數
Object[] paramsArray = joinPoint.getArgs();

//以原來的引數列表執行目標方法
Object returnObject = joinPoint.proceed();

//以自定義引數列表執行目標方法
Object returnObject = joinPoint.proceed(paramsArray);

關於多個切面的執行順序

由於通過AOP實現,程式得到了很好的解耦,但是也會帶來一些問題,比如:我們可能會對Web層做多個切面,校驗使用者,校驗頭資訊等等,這個時候經常會碰到切面的處理順序問題。

所以要定義每個切面的優先順序,我們需要@Order(i)-(直接新增在切面類上)註解來標識切面的優先順序。

i值越小,優先順序越高。

假設我們還有一個切面是CheckNameAspect用來校驗name必須為jack,我們為其設定@Order(10),而上文中WebLogAspect設定為@Order(5),所以WebLogAspect有更高的優先順序,這個時候執行順序是這樣的:

在@Before中優先執行@Order(5)的內容,再執行@Order(10)的內容 
在@After和@AfterReturning中優先執行@Order(10)的內容,再執行@Order(5)的內容

所以我們可以這樣子總結:

  • 在切入點前的操作,按order的值由小到大執行
  • 在切入點後的操作,按order的值由大到小執行

總結

AOP(Aspect Oriented Programming),即面向切面程式設計,可以說是OOP(Object Oriented Programming,面向物件程式設計)的補充和完善。OOP引入封裝、繼承、多型等概念來建立一種物件層次結構,用於模擬公共行為的一個集合。不過OOP允許開發者定義縱向的關係,但並不適合定義橫向的關係,例如日誌功能。日誌程式碼往往橫向地散佈在所有物件層次中,而與它對應的物件的核心功能毫無關係對於其他型別的程式碼,如安全性、異常處理和透明的持續性也都是如此,這種散佈在各處的無關的程式碼被稱為橫切(cross cutting),在OOP設計中,它導致了大量程式碼的重複,而不利於各個模組的重用。

AOP技術恰恰相反,它利用一種稱為"橫切"的技術,剖解開封裝的物件內部,並將那些影響了多個類的公共行為封裝到一個可重用模組,並將其命名為"Aspect",即切面。所謂"切面",簡單說就是那些與業務無關,卻為業務模組所共同呼叫的邏輯或責任封裝起來,便於減少系統的重複程式碼,降低模組之間的耦合度,並有利於未來的可操作性和可維護性。

使用"橫切"技術,AOP把軟體系統分為兩個部分:核心關注點橫切關注點。業務處理的主要流程是核心關注點,與之關係不大的部分是橫切關注點。橫切關注點的一個特點是,他們經常發生在核心關注點的多處,而各處基本相似,比如許可權認證、日誌、事物。AOP的作用在於分離系統中的各種關注點,將核心關注點和橫切關注點分離開來。

原始碼下載

[相關示例完整程式碼]請獲取 相關分支哦:feature-20180910-web