一、返回通知(返回通知的一个特点是可以访问到方法的返回值,可以对方法的返回值进行拦截)
思考问题:与后置通知进行比较。后置通知不管目标方法是否抛出异常都能得到执行(因为有异常的捕获机制)。
返回通知,紧挨着目标方法执行的代码,所以要等到目标方法正常执行之后得以执行,并且因为紧挨着目标方法,所以返回通知可以访问到目标方法的返回值。
后置通知:是否可以改变方法的返回值。
我的思考:这样来理解。返回通知可以访问到方法的返回值。
思考问题:能不能改变方法的返回值呢?
我的答案:不能。回家自己尝试一下。
示例代码:
/**
* 在方法法正常结束后执行的代码,返回通知是可以访问到方法的返回值的。
* @param jp
* @param result
*/
@AfterReturning(value="execution(public int com.liwei.aop.ArithmeticCalculator.*(int,int))",returning="result")
public void afterReturnMethod(JoinPoint jp,Object result){
String method_name = jp.getSignature().getName();
Object[] args = jp.getArgs();
System.out.println("【返回通知】被增强处理的方法名:" + method_name + "执行完毕,返回值为:" + result);
}
二、异常通知
示例代码:
/**
* 在目标方法出现异常时会执行的代码。
* 可以访问到异常对象,且可以指定在出现“特定异常”时再执行通知代码。
* @param jp
* @param ex
*/
@AfterThrowing(value="execution(public int com.liwei.aop.ArithmeticCalculator.*(int,int))",throwing="ex")
public void afterThrowing(JoinPoint jp,ArithmeticException ex){
String method_name = jp.getSignature().getName();
Object[] args = jp.getArgs();
System.out.println("【异常通知】被增强处理的方法名:" + method_name + "抛出异常,异常消息为:" + ex.getMessage());
}
三、环绕通知(最像 JDK 的动态代理,而且环绕通知必须写返回值,并且可以修改返回值,并且返回通知必须携带 ProceedingJoinPoint 类型的参数)
示例代码:
package com.liwei.aop.spring;
import java.util.Arrays;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(1)
@Aspect
@Component
public class ValidateAspect {
/**
* 环绕通知需要携带 ProceedingJoinPoint 类型的参数。(必须携带)
* 环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法。
* 且环绕通知必须有返回值, 返回值即为目标方法的返回值。
* @param pjd
* @return
*/
@Around(value="execution(public int com.liwei.aop.ArithmeticCalculator.add(int, int))")
public Object aroundMethod(ProceedingJoinPoint pjd){
Object result = null;
String method_name = pjd.getSignature().getName();
Object[] args = pjd.getArgs();
try {
// 前置通知
System.out.println("【 Validate 前置通知】参数验证。。。" + "被验证的方法名为:" + method_name + ",参数为:" + Arrays.asList(args));
// 执行目标方法
result = pjd.proceed();
// 返回通知
System.out.println("【 Validate 返回通知】参数验证。。。" + "被验证的方法名为:" + method_name + "执行结束,返回值为:" + result);
} catch (Throwable e) {
e.printStackTrace();
// 异常通知
System.out.println("【 Validate 异常通知】参数验证。。。" + "被验证的方法名为:" + method_name + "执行结束,抛出的异常信息:" + e.getMessage());
}
// 后置通知
System.out.println("【 Validate 后置通知】参数验证。。。" + "被验证的方法名为:" + method_name + "执行结束。" );
return result;
}
}
执行结果: