一、切面的优先级
- 什么场景需要指定切面的优先级:
多个切面的通知指定同一个目标方法
时,哪个切面的通知先执行,哪个切面通知后执行,顺序是不确定的。
- 如何指定切面的优先级
① 可以在切面上使用 @Order("序号")
注解指定切面的优先级,序号用整数表示,数值越小,优先级越高
。
② 也可以实现Ordered接口,getOrder() 方法返回的值越小,优先级越高。
- 举个例子:
@Order(1)
@Aspect
@Component
public class LoggingApsect
{
...
}
@Order(0)
@Aspect
@Component
public class ValidationApsect
{
...
}
二、重用切入点表达式
- 如何重用切入点表达式:
① 使用 @Pointcut("切入点表达式")
注解声明一个简单的方法。方法体通常是空的,方法的修饰符,控制着这个切入点表达式的可见性,如果需要被多个切面引用,可以声明为public。
② 同切面
的通知可以根据方法名
引用该切入点表达式。
同一个包
下切面的通知需要通过 类名.方法名
引入该切入点表达式。
不同包
下切面的通知需要通过 包名.类名.方法名
引入该切入点表达式。
- 重用切入点表达式的好处 :
在AspectJ切面中,多个通知切入点表达式可能会相同,所以使用切入点表达式可以减少重复代码。
- 举个例子:
@Aspect
@Component
public class LoggingApsect
{
/**
* 1.定义一个方法,用于声明切入点表达式.一般情况下,该方法体为空;
* 2.使用@Pointcut()声明切入点表达式;
* 3.相同切面的其他通知,直接使用: 方法名() 来引用切入点表达式;
* 4.同包下的不同切面,引用时需要加上类名;
* 5.不同包下的切面,引用时需要加上包名.类名;
*/
@Pointcut("execution(* com.sqp.spring.aop.dao.MyCalculator.*(..))")
public void declarePointcutExpression(){};
/**
* 前置通知:
* 声明该方法是一个前置通知: 在目标方法执行之前执行前置通知(使用execution()指定目标方法)
* @param joinPoint
*/
@Before("declarePointcutExpression()")
public void beforeAdvice(JoinPoint joinPoint)
{
String methodName = joinPoint.getSignature().getName();
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("The method [" + methodName + "] input params is " + args);
}
}