返回通知 异常通知 环形通知
1.LoggingAspect.java切面类
环形通知包括所有前置 后置 返回 异常
package com.spring.aop.impl2;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
// /*
// * 在方法正常结束受执行的代码
// * 返回通知可以访问到返回值
// */
// @AfterReturning(value="execution(public int com.spring.aop.impl2.AtithmeticCalculatior.*(..))",
// returning="result")
// public void afterReturning(JoinPoint joinPoint,Object result)
// {
// String methodname=joinPoint.getSignature().getName();
// System.out.println("The method "+methodname+" ends with "+result);
// }
//
// /*
// * 在目标方法出现异常时执行的代码
// * 可以访问到异常对象,且可以指定在出现特定异常时在执行通知代码
// */
// @AfterThrowing(value="execution(public int com.spring.aop.impl2.AtithmeticCalculatior.*(..))",
// throwing="ex")
// public void afterThrowing(JoinPoint joinPoint,Exception ex)
// {
// String methodname=joinPoint.getSignature().getName();
// System.out.println("The method "+methodname+" occurs excetion: "+ex);
// }
/*
* 环绕通知需要携带ProceedingJoinPoint类型的参数
* 环绕通知类似于动态代理的全过程ProceedingJoinPoint类型的参数可以决定是否执行目标方法
* 且环绕通知必须有返回值,返回值即目标方法的返回值
*/
@Around("execution(public int com.spring.aop.impl2.AtithmeticCalculatior.*(..))")
public Object aroundMethod(ProceedingJoinPoint pjd) {
String methodname=pjd.getSignature().getName();
Object result=null;
try {
//前置通知
System.out.println("The method begins "+methodname+" begins with "+Arrays.asList(pjd.getArgs()));
//执行目标方法
result=pjd.proceed();
//返回通知
System.out.println("The method "+methodname+" ends with "+result);
} catch (Throwable e) {
//异常通知
System.out.println("The method "+methodname+" occurs exception: "+e);
e.printStackTrace();
}
//后置通知
System.out.println("The method "+methodname+" ends");
return result;
}
}
2.切面AOP的优先级
依靠@Order(num) num 越小优先级越高
另一个切面验证类
package com.spring.aop.impl2;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(1)
@Aspect
@Component
public class VlidationAspect {
@Before("execution(public int com.spring.aop.impl2.AtithmeticCalculatior.*(..))")
public void validateArgs(JoinPoint joinPoint) {
System.out.println("validate: "+Arrays.asList(joinPoint.getArgs()));
}
}
3.重用切点表达式
package com.spring.aop.impl2;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(2)
@Aspect
@Component
public class LoggingAspect {
/*
* 定义一个方法 用于声明切入点表达式,该方法中不需要添加其他代码
* 只需要把方法名复制给各个方法
*
*/
@Pointcut("execution(public int com.spring.aop.impl2.AtithmeticCalculatior.*(..))")
public void declareJointPointExpression() {
}
/*
* 在方法正常结束受执行的代码
* 返回通知可以访问到返回值
*/
@AfterReturning(value="declareJointPointExpression()")
public void afterReturning(JoinPoint joinPoint,Object result)
{
String methodname=joinPoint.getSignature().getName();
System.out.println("The method "+methodname+" ends with "+result);
}
/*
* 在目标方法出现异常时执行的代码
* 可以访问到异常对象,且可以指定在出现特定异常时在执行通知代码
*/
@AfterThrowing(value="declareJointPointExpression()")
public void afterThrowing(JoinPoint joinPoint,Exception ex)
{
String methodname=joinPoint.getSignature().getName();
System.out.println("The method "+methodname+" occurs excetion: "+ex);
}
return result;
}
}
外部的类中实现重用表达式
package com.spring.aop.impl2;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Order(1)
@Aspect
@Component
public class VlidationAspect {
/*
在同一包下时只需写类名方法就行 ,若不是同一包下需要写上包名
com.spring,aop.impl2
*/
@Before("LoggingAspect.declareJointPointExpression()")
public void validateArgs(JoinPoint joinPoint) {
System.out.println("validate: "+Arrays.asList(joinPoint.getArgs()));
}
}