springboot教程-@Around注解

上接:springboot教程-aop注解 @Aspect、@Before、@After、@AfterReturning、 @AfterThrowing

概述

本文介绍 Around 通知

修改 Logger 类

增加下面方法:

@Around("pt()")
public void aroundPrint(){
    System.out.println("======around");
}

完整代码

package top.malaoshi.aop;

@Component
//表明该类为切面类
@Aspect
public class Logger {
    /*
    在 top.malaoshi.controller 包下的类 的 方法,都能注入代码
     */
    @Pointcut("execution(* top.malaoshi.controller.*.*(..))")
    public void pt(){
    }
    /*
    在 top.malaoshi.controller 包下的类 的 方法,执行之前 会先执行下面方法
     */
    @Before("pt()")
    public void beforePrint(){
        System.out.println("=======before");
    }
    /*
    在 top.malaoshi.controller 包下的类 的 方法,执行之后(不论是否抛异常) 会执行下面方法
     */
    @After("pt()")
    public void afterPrint(){
        System.out.println("======after");
    }
    /*
    在 top.malaoshi.controller 包下的类 的 方法,执行之后(没抛异常) 会执行下面方法
     */
    @AfterReturning("pt()")
    public void afterReturningPrint(){
        System.out.println("======afterReturning");
    }
    /*
    在 top.malaoshi.controller 包下的类 的 方法,执行之后(抛异常了) 会执行下面方法
     */
    @AfterThrowing("pt()")
    public void afterThrowingPrint(){
        System.out.println("======异常通知afterThrowingPrint");
    }

    @Around("pt()")
    public void aroundPrint(){
        System.out.println("======around");
    }
}

修改 Controller

让方法能 执行成功

完整代码

@RestController
public class StudentCtrl {

    @RequestMapping("/test")
    public JsonResult test() {
        System.out.println("test()");
//        int i=1/0;
        return new JsonResult(0,"执行成功!");
    }
}

测试(有问题)

访问该Controller,执行结果如下:

======around
======after
======afterReturning

发现 没有执行 目标方法

解决问题

around环绕通知 ProceedingJoinPoint 形参

需要在 环绕方法中传入形参 ProceedingJoinPoint ,该类有以下作用:

  1. 通过该类获取 传入目标方法的形参
  2. 通过该类 调用目标方法
  3. 通过该类 获取目标方法的返回结果

修改Logger类的 aroundPrint 方法

@Around("pt()")
public Object aroundPrint(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("======around开始");
    //获取传入的目标方法的参数
    Object[] array=pjp.getArgs();
    //调用目标方法,并返回结果
    Object res=null;
    try {
        res = pjp.proceed(array);
        System.out.println("======around结束");
    }catch (Throwable e){
        System.out.println("======around捕捉异常");
        throw e;
    }
    return res;
}

注意: pjp.proceed() 方法会抛出异常,不要 catch 该异常,否则不会触发 @AfterThrowing 通知

测试-执行成功

执行结果如下:

======around开始
=======before
test()
======around结束
======after
======afterReturning

执行成功顺序

  1. around 开始
  2. before
  3. 目标方法
  4. around 结束
  5. after
  6. afterReturning

测试-执行抛出异常

修改 Controller

让其抛出异常

@RequestMapping("/test")
public JsonResult test() {
    System.out.println("test()");
    int i=1/0;//抛出异常
    return new JsonResult(0,"执行成功!");
}

执行

执行结果如下:

======around开始
=======before
test()
======around捕捉异常
======after
======异常通知afterThrowingPrint

执行抛出异常的顺序

  1. around 开始
  2. before
  3. 目标方法
  4. around 捕捉异常
  5. after
  6. afterThrowing

总结

一般使用 @Around 注解可以代替 @Before、@After、@AfterReturning、@AfterThrowing


原文出处:/show_1IXjKPnESlF.html