重用切点表达式
看之前的代码:
package com.spring.aop;
import java.util.Arrays;
import java.util.List;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
/**
* 声明该类为切面:
* 1.让IOC容器创建这个类的bean(@Component)
* 2.声明为切面(@Aspect)
*/
@Order(2)
@Aspect
@Component
public class LoggingAspect {
//声明这是一个前置通知
@Before("execution(* com.spring.aop.Calculator.*(..))")
public void beforeMethod(JoinPoint joinPoint){
//注意,JoinPoint来自org.aspectj.lang.JoinPoint,小心导错包
//执行方法名
String methodName = joinPoint.getSignature().getName();
//执行方法参数
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("前置通知:method 【"+methodName+"】 begin:"+args);
}
@After("execution(* com.spring.aop.Calculator.*(..))")
public void afterMethod(JoinPoint joinPoint){
//执行方法名
String methodName = joinPoint.getSignature().getName();
//执行方法参数
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("后置通知:method 【"+methodName+"】 end:"+args);
}
@AfterReturning("execution(* com.spring.aop.Calculator.*(..))")
public void afterRunning(JoinPoint joinPoint){
//执行方法名
String methodName = joinPoint.getSignature().getName();
//执行方法参数
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("返回通知:method 【"+methodName+"】 end:"+args);
}
@AfterThrowing(value="execution(* com.spring.aop.Calculator.*(..))",throwing="ex")
public void afterThrowing(JoinPoint joinPoint,Exception ex){
//执行方法名
String methodName = joinPoint.getSignature().getName();
//执行方法参数
List<Object> args = Arrays.asList(joinPoint.getArgs());
System.out.println("异常通知:method 【"+methodName+"】 end:"+args+",异常:"+ex);
}
}
在每个通知上重复的使用了同一个切点,可以将之抽取出来:
新建一个计算器切点类:
- CalculatorPointCut
package com.spring.aop;
import org.aspectj.lang.annotation.Pointcut;
public class CalculatorPointCut {
/**
* 声明切点表达式
* 不需要写任何别的代码
*/
@Pointcut("execution(* com.spring.aop.Calculator.*(..))")
public void declareJoinPointExpression(){}
}
声明切点表达式供计算器切面的通知使用
如:
@Before("com.spring.aop.CalculatorPointCut.declareJoinPointExpression()")
public void beforeMethod(JoinPoint joinPoint){...}
- 直接在切面的通知的value中调用定义的切点方法
- 如果两个类在同一个包内,科直接使用”类名.方法”的方法是调用
- 可以在切面类中直接定义一个切点方法,这样在当前切面类中就可以直接调用,而别的切面类也都可以通过类命名调用。