一篇文章带你搞定 SpringBoot 整合 AOP

对于 AOP 的知识在 Spring 学习章节已经进行过学习:一篇文章帮你搞定 Spring

本篇文章主要讲述如何在 SpringBoot 中使用 AOP

示例场景:比如项目已经上线,某个环节运行速度特别慢,需要对其单独打印日志测试一下,挨个去改很显然不靠谱,因此可以借助AOP,将该段代码嵌入到业务中,检测完成后,再移出掉即可。

一、前期配置

在这里插入图片描述
同时需要我们pom 中引入 aop 依赖

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

二、前置/后置/异常/最终通知的实现

这里的实现类似于:一篇文章帮你搞定 Spring 基于注解的AOP配置
目录结构:
在这里插入图片描述
UserService:

@Service
public class UserService {
    public String getUsernameById(Integer id) {
        System.out.println("UserService 执行 getUsernameById >>>> " + id);
        return "Yolo";
    }

    public void getUsernameError(String name) {
        System.out.println("UserService 执行 getUsernameByName >>>> " + name);
        int i = 3/0;
    }
}

UserController:

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserService userService;

    @GetMapping("/id")
    public String getUserById(int id) {
        return userService.getUsernameById(id);
    }

    @GetMapping("/error")
    public void getError(){
        System.out.println("进来了。。。。。。");
        userService.getUsernameError("yolo");
    }
}

LogComponent

@Component
@Aspect
public class LogComponent {
    /**
     * 对com.yolo.aop.service包下的所有方法进行增强
     */
    @Pointcut("execution(* com.yolo.aop.service.*.*(..))")
    public void pc1() {
    }

    //前置通知
    @Before(value = "pc1()")
    public void before(JoinPoint jp) {
        String name = jp.getSignature().getName();
        System.out.println("前置通知 >>> " + name);
    }

    //后置通知
    @AfterReturning(value = "pc1()", returning = "result")
    public void afterReturning(JoinPoint jp, Object result) {
        String name = jp.getSignature().getName();
        System.out.println("后置通知 >>> " + name + " >>> " + result);
    }

    //异常通知
    @AfterThrowing(value = "pc1()", throwing = "e")
    public void afterThrowing(JoinPoint jp, Exception e) {
        String name = jp.getSignature().getName();
        System.out.println("异常通知 >>> " + name + " >>> " + e.getMessage());
    }

    //最终通知
    @After(value = "pc1()")
    public void after(JoinPoint jp) {
        String name = jp.getSignature().getName();
        System.out.println("最终通知 >>> " + name);
    }
}

在这里插入图片描述
测试异常通知:
在这里插入图片描述

三、环绕通知的实现

@Component
@Aspect
public class LogComponent {
    /**
     * 对com.yolo.aop.service包下的所有方法进行增强
     */
    @Pointcut("execution(* com.yolo.aop.service.*.*(..))")
    public void pc1() {
    }

    //环绕通知
    @Around("pc1()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object rtValue = null;
        try {
            //得到方法执行所需的参数
            Object[] args = pjp.getArgs();
            System.out.println("args >>> " + args);
            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。前置");
            //明确调用业务层方法(切入点方法)
            rtValue = pjp.proceed(args);
            System.out.println("rtValue >>> " + rtValue);
            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。后置");

            return rtValue;
        } catch (Throwable t) {
            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。异常");
            throw new RuntimeException(t);
        } finally {
            System.out.println("Logger类中的aroundPringLog方法开始记录日志了。。。最终");
        }
    }
}

在这里插入图片描述
测试异常通知:
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章