Springboot3中aop几个通知注解执行的先后顺序

1、简介

        随着Spring框架的不断更新迭代,在面向切面编程中,Spring AOP使用 @Around(在方法执行前后) 、@Before(在方法执行前)、 @AfterReturning(未抛异常) 、 @After(不论是否抛异常) 、 @Around (在方法执行后)

2、注解描述

注解 描述
@Before 在代理方法执行前执行
@After 在代理方法执行后执行
@AfterReturning 在代理方法执行返回后执行
@AfterThrowing 在代理方法抛异常时执行
@Around 包围着代理方法执行
@Pointcut 定义切面

3、@Pointcut注解的使用

        @Pointcut中可以指定execution表达式和其他例如args、within、target等表达式,execution 最为常用,其使用具体模式如下:

execution(<修饰符模式> <返回类型模式><方法名模式>(<参数模式>)<异常模式>) 
# 返回类型模式、方法名模式和参数模式外,其它项都是可选的
# 示例:在com.test包及其子包下所有Controller中所有方法都是被代理的方法
@Pointcut("execution(public * com.test..*Controller.*(..))")

        表达式中通配符的含义:

.. # 在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。
*  # 配任何数量字符(只能代表一个字符串,用在方法中代表一个任意类型参数)。
+  # 匹配指定类型的子类型;仅能作为后缀放在类型模式后边

 4、通知注解使用@PointCut

 4.1、定义连接点

@Pointcut("execution(public * com.weilong..*Controller.*(..))")
public void controllerPointcut(){}

4.2、通知注解关联连接点

@Before("controllerPointcut()")
@After("controllerPointcut()")
@Around("controllerPointcut()")
@AfterThrowing("controllerPointcut()")
@AfterReturning("controllerPointcut()")

5、测试通知注解执行顺序

5.1、准备测试类

5.1.1、切面类

import com.alibaba.fastjson.JSONObject;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.reflect.Modifier;

@Aspect
@Component
@Slf4j
public class LogAspect1 {

    public LogAspect1(){
        System.out.println("LogAspect");
    }

    // excution表达式标识符解释:execution(<修饰符模式>?<返回类型模式><方法名模式>(<参数模式>)<异常模式>?) 返回类型模式、方法名模式和参数模式外,其它项都是可选的
    // ..:在类型模式中匹配任何数量子包;而在方法参数模式中匹配任何数量参数。
    // *:匹配任何数量字符(只能代表一个字符串,用在方法中代表一个任意类型参数)。
    @Pointcut("execution(public * com.test..*Controller.*(..))")
    public void controllerPointcut(){

    }

    // 在sprintboot3中aop注解执行顺序:
    // @Around (在方法执行前) -> @Before -> @AfterReturning(未抛异常) -> @After(不论是否抛异常) -> @@Around (在方法执行后)
    @Before("controllerPointcut()")
    public void doBefore(JoinPoint joinPoint){
        log.info(" @Before...");
    }

    // ProceedingJoinPoint对象是JoinPoint的子接口,该对象只用在@Around的切面方法中
    @Around("controllerPointcut()")
    public Object doAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        // Object proceed() throws Throwable //执行目标方法
        // Object proceed(Object[] var1) throws Throwable //传入的新的参数去执行目标方法
        log.info(" @Around...方法前");
        Object result = proceedingJoinPoint.proceed();
        log.info(" @Around...方法后");
        return result;
    }
    @After("controllerPointcut()")
    public void after(JoinPoint joinPoint){
        log.info(" @After...");
    }

    @AfterThrowing("controllerPointcut()")
    public void afterThrow(JoinPoint joinPoint){
        log.info(" @AfterThrowing...");
    }

    @AfterReturning("controllerPointcut()")
    public void afterReturn(JoinPoint joinPoint){
        log.info(" @AfterReturning...");
    }
}

 5.1.2、Controller类

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @GetMapping(value = "/hello")
    public String test(){
        //int i = 1 / 0;  // 测试抛异常放开
        return "hello world!";
    }
}

5.2、代理方法未抛出异常

        执行顺序如下:

4c1128aa43354ec197c935220cb5ed37.png

5.3、代理方法抛出异常

        执行顺序如下:      

34da1ee76c4b4c7c80def556c5c926ca.png

  6、总结

        本文详细介绍了Springboot3中aop在两种情况下通知的执行顺序,关于更多aop深入知识将在后续博文中更新。

 

相关推荐

  1. 用于接收参数注解

    2024-04-28 18:42:04       32 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-28 18:42:04       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-28 18:42:04       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-28 18:42:04       82 阅读
  4. Python语言-面向对象

    2024-04-28 18:42:04       91 阅读

热门阅读

  1. 处理跨域问题:CORS错误

    2024-04-28 18:42:04       26 阅读
  2. MogDB如何兼容Oracle的管道函数

    2024-04-28 18:42:04       31 阅读
  3. Swift - swiftc

    2024-04-28 18:42:04       30 阅读
  4. 简单仓库管理系统(增删改查功能)

    2024-04-28 18:42:04       21 阅读
  5. Shell教程基础

    2024-04-28 18:42:04       25 阅读
  6. CSS合集

    2024-04-28 18:42:04       39 阅读
  7. 外贸独立站注册域名应该注意的事项

    2024-04-28 18:42:04       34 阅读
  8. Typescript 学习笔记

    2024-04-28 18:42:04       33 阅读
  9. nginx负载均衡策略

    2024-04-28 18:42:04       36 阅读
  10. golang sync pool

    2024-04-28 18:42:04       24 阅读
  11. 陕西省工程系列高级职称评审申报指南

    2024-04-28 18:42:04       34 阅读
  12. Viewpage+TabLayout+Fragment常用功能实现

    2024-04-28 18:42:04       35 阅读