Before、AfterReturning、AfterThrowing、After、Around
不管配置哪種Advice,都需要指定2個屬性:
- method:指定將哪個方法轉換成Advice。
- pointcut或pointcut-ref:pointcut直接指定切入點表達式;pointcut-ref引入已有的切入點表達式。
- Before:在目標執行之前織入的Advice。
- AfterReturning:在目標方法成功完成之後織入的Advice
可額外指定一個returning屬性,該屬性值有2個作用:
Advice方法可通過該屬性指定的值來訪問目標方法的返回值。
Advice方法聲明該返回值類型時,限制目標方法的返回值必須是指定的類型。否則該Advice不會織入。如果不想對目標方法的返回值進行限制,可將該返回值聲明爲Object。
- AfterThrowing:在目標方法出現異常時織入的Advice。這種Advice類似於catch塊。
可額外指定一個throwing屬性,該屬性值有2個作用:
Advice方法可通過該屬性指定的值來訪問目標方法拋出的異常。
Advice方法聲明該異常類型時,限制目標方法的拋出的異常必須是指定的類型。否則該Advice不會織入。如果不想對目標方法拋出的異常進行限制,可將該異常聲明爲Exception或Throwable。
- After:不管目標方法成功完成,還是異常結束,該Advice都會織入。這種Advice類似於finally塊。(可以用來釋放資源)
- Around:這種Advice功能最強大,它既可以訪問、修改目標方法調用參數,也可訪問、修改目標方法的返回值。它甚至完全阻止目標方法的執行。它既可在目標方法之前織入,也可在目標方法之後織入。它是線程不安全,能用其他Advice搞定的,就不要把Around Advice拿出來。
Around Advice方法必須滿足以下3點:
- 必須聲明返回值類型。
- 必須聲明一個類型爲org.aspectj.lang.ProceedingJoinPoint類型的形參。
- 必須調用ProceedingJoinPoint形參的proceed()方法,這就是回調目標方法。如果沒有這一行,目標方法不會執行。
package com.lwy.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
public class AroundAdviceAspect {
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("模擬開啓事務");
/**
* ProceedingJoinPoint繼承了JoinPoint,JoinPoint包含了如下方法:
* getArgs:獲取目標方法調用參數
* getKind:獲取連接點類型
* getSignature:獲取目標方法的方法簽名
* getTarget:獲取目標對象
* getThis:獲取AOP代理
*/
//訪問到目標方法的調用參數
Object[] args = pjp.getArgs();
// ------------------以上在目標方法之前織入------------------
// 回到原來的目標方法,如果去掉此行,目標方法就不會執行
Object returnObject = pjp.proceed(args);
// ------------------以下在目標方法之前織入------------------
System.out.println("模擬關閉事務");
return returnObject;
}
}
五種Advice的功能總結:
|
Before |
AfterReturning |
AfterThrowing |
After |
Around |
訪問調用參數 |
Y |
Y |
Y |
Y |
Y |
修改調用參數 |
N |
N |
N |
N |
Y |
阻止目標方法執行 |
Y(拋異常) |
N |
N |
N |
Y |
訪問返回值 |
N |
Y |
N |
N |
Y |
修改返回值 |
N |
N |
N |
N |
Y |
AOP的切入點指示符:
Execution([訪問權限] [返回值類型] 包.類.方法(形參) [throws 異常])
形參列表:.. 代表任意個任意類型的參數;* 代表1個任意類型的參數
例如:(*,java.lang.String):2個形參,且第二個形參類型爲java.lang.String