1. 程式人生 > >Spring AOP切面實現:引數傳遞

Spring AOP切面實現:引數傳遞

通知方法引數注入:

在Spring AOP中,除了execution和bean指示符不能傳遞引數給通知方法,其他指示符都可以將匹配的相應引數或物件自動傳遞給通知方法。

1、獲取匹配的引數

通過"argNames"屬性指定引數名。

@Before(value="args(param)", argNames="param") //明確指定了  
public void beforeTest(String param) {  
    System.out.println("param:" + param);  
}

args、argNames的引數名與beforeTest()方法中引數名 保持一致,即param

使用args指示符,可以不利用argNames宣告引數

@Before("execution(public * com.learn..*.show(..)) && args(userId,..)")
    public void beforeTest(int userId) {
        System.out.println("userId:" + userId);
    }

args的引數名與beforeTest()方法中引數名 保持一致,即param

2、獲取匹配的物件

例:

@Pointcut(value="@annotation(t)",argNames = "t")
	public void annotationTest(Table t)
	{
	}
	
    //引用時帶上類名
	@After(value = "annotationTest(t)")
	public void after(Table t)
	{
		System.out.println("呼叫LearnAspect的切入點pointcut()");
	}
Table是一個自定義註解。要獲取該物件,annotationTest方法要先在方法中定義新增該引數,再利用argNames宣告,切入點表示式也要改為引數名。即t

JoinPoint獲取引數:

Spring AOP提供使用org.aspectj.lang.JoinPoint型別獲取連線點資料,任何通知方法的第一個引數都可以是JoinPoint(環繞通知是ProceedingJoinPoint,JoinPoint子類)。

(1)JoinPoint:提供訪問當前被通知方法的目標物件、代理物件、方法引數等資料

(2)ProceedingJoinPoint:只用於環繞通知,使用proceed()方法來執行目標方法

如引數型別是JoinPoint、ProceedingJoinPoint型別,可以從“argNames”屬性省略掉該引數名(可選,寫上也對),這些型別物件會自動傳入的,但必須作為第一個引數

例:

切面:

@Pointcut(value="args(p)")
	public void argsTest(int p)
	{
	}
	
	@Before(value="argsTest(p)",argNames="p")
	public void afterTest(JoinPoint jp,int p)
	{
		Object[] o = jp.getArgs();
		System.out.println(o[0]);
		System.out.println(p);
		System.out.println("args");
	}
結果:
1  //利用JoinPoint獲取引數
1  //利用引數注入獲取引數
args
This is showTime

AfterReturning 獲取請求返回值:

@Pointcut("execution(public * com.learn.spring..*.*(*))")
	public void pointcut() {
	}
	
	/*
	 *配置後置通知返回,使用在方法pointcut()上註冊的切入點 
	 */
	@AfterReturning(pointcut="pointcut()", returning="returnValue")
	public void afterReturn(Object returnValue)
	{
		System.out.println("afterReturn  "+returnValue);
	}
注意:

1、returning引數名與afterReturn()方法引數名相同,即都為returnedValue.

2、AfterRetruning含有返回值時,不能和Around指示符使用同一個pointcut。返回值會為null,報錯:

org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: ....

AfterThrowing 獲取請求丟擲異常:

@Pointcut("execution(public * com.learn.spring..*.*(*))")
	public void pointcut() {
	}
	/*
	 * 配置丟擲異常後通知,使用在方法pointcut()上註冊的切入點
	 */
	@AfterThrowing(pointcut="pointcut()",throwing="ex")
	public void afterThrow(Exception ex)
	{
		System.out.println("afterThrow "+ex.getMessage());
	}

throwing引數名與afterThrow()方法引數名相同,即ex