一、环绕通知
环绕通知是所有通知类型中功能最为强大的,能够全面地控制连接点.甚至可以控制是否执行连接点.
对于环绕通知来说,连接点的参数类型必须是ProceedingJoinPoint .它是JoinPoint的子接口,允许控制何时执行,是否执行连接点.
在环绕通知中需要明确调用 ProceedingJoinPoint的proceed()方法来执行被代理的方法.如果忘记这样做就会导致通知被执行了,但目标方法没有被执行.
注意:环绕通知的方法需要返回目标方法执行之后的结果,即调用joinPoint.proceed();的返回值,否则会出现空指针异常
(1)环绕通知需要携带 ProceedingJoinPoint 类型的参数.
(2)环绕通知类似于动态代理的全过程: ProceedingJoinPoint 类型的参数可以决定是否执行目标方法.
且环绕通知必须有返回值, 返回值即为目标方法的返回值
@Around("execution(* com..Spring4.AOP.*.*(..))")
public Object aroundMethod(ProceedingJoinPoint pjd){
Object result = null;
String methodName = pjd.getSignature().getName();
try {
//前置通知
System.out.println("The method " + 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);
throw new RuntimeException(e);
}
//后置通知
System.out.println("The method " + methodName + " ends");
return result;
}
二、指定切面的优先级在同一个连接点上应用不止一个切面时, 除非明确指定, 否则它们的优先级是不确定的.
切面的优先级可以通过实现 Ordered 接口或利用 @Order 注解指定.
实现 Ordered 接口, getOrder() 方法的返回值越小, 优先级越高.
若使用 @Order 注解, 序号出现在注解中
三、重用切入点定义
在编写 AspectJ 切面时, 可以直接在通知注解中书写切入点表达式.但同一个切点表达式可能会在多个通知中重复出现.
在 AspectJ切面中,可以通过@Pointcut注解将一个切入点声明成简单的方法.切入点的方法体通常是空的,因为将切入点定义与应用程序逻辑混在一起是不合理的.
切入点方法的访问控制符同时也控制着这个切入点的可见性.如果切入点要在多个切面中共用,最好将它们集中在一个公共的类中.在这种情况下,它们必须被声明为public.在引入这个切入点时,必须将类名也包括在内.如果类没有与这个切面放在同一个包中,还必须包含包名.
其他通知可以通过方法名称引入该切入点.
<strong> </strong> /**
* 定义一个方法, 用于声明切入点表达式. 一般地, 该方法中再不需要添入其他的代码.
* 使用 @Pointcut 来声明切入点表达式.
* 后面的其他通知直接使用方法名来引用当前的切入点表达式.
*/
@Pointcut("execution(public int com.Spring4.AOP.ArithmeticCalculator.*(..))")
public void declareJointPointExpression(){}
在通知注解中直接引用方法名即可 @Before("declareJointPointExpression()")