1 创建切面
使用 @Aspect 注解创建切面
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(* cn.xxx..*ServiceImpl.*(..))")
public void printLog() {
}
@Before("printLog()")
public void before(JoinPoint jp) {
}
@After("printLog()")
public void after(JoinPoint jp) {
}
@AfterReturning(pointcut = "execution(* cn.xxx..*ServiceImpl.*(..))", returning = "returnVal")
public void afterReturn(JoinPoint jp, String returnVal) {
}
@AfterThrowing(value = "printLog()", throwing = "e")
public void afterThrow(JoinPoint jp, Throwable e) {
}
}
2 通知注解
- @After(最终通知):通知方法会在目标方法返回或抛出异常后调用
- @AfterReturning(后置通知):通知方法会在目标方法返回后调用
- @AfterThrowing(异常通知):通知方法会在目标方法抛出异常后调用
- @Around(环绕通知):通知方法会将目标方法封装起来
- @Before(前置通知):通知方法会在目标方法调用之前执行
3 JoinPoint
常用的方法
- Object[] getArgs:返回目标方法的参数
- Signature getSignature:返回目标方法的签名
- Object getTarget:返回被织入增强处理的目标对象
- Object getThis:返回AOP框架为目标对象生成的代理对象
当使用 @Around 处理时,需要将第一个参数定义为 ProceedingJoinPoint 类型,该类是 JoinPoint 的子类。
4 切面执行顺序
4.1 被一个 Aspect 类拦截
正常:
异常:
4.2 被多个 Aspect 类拦截
1)执行顺序
优先级高的切面先执行,同一切面增强类型优先的先执行,增强类型相同的随机执行
2)指定优先级
- 让切面类实现 org.springframework.core.Ordered 接口:实现该接口的 int getOrder() 方法,该方法返回值越小,优先级越高
- 直接使用 @Order 注解来修饰一个切面类:使用这个注解时可以配置一个 int 类型的 value 属性,该属性值越小,优先级越高