SpringBoot之AOP执行顺序

在现代软件开发中,面向切面编程(Aspect-Oriented Programming, AOP)是一种强大的编程范式,它提供了一种更清晰、更集中地管理交叉关注点(如日志记录、安全性和事务管理)的方法。在 Spring Boot 中,AOP 被广泛应用于各种场景。本文将详细介绍 Spring Boot 中 AOP 的执行顺序,通过具体的代码示例和执行流程图解来帮助您深入理解 AOP 的执行逻辑。

AOP 基本概念

在深入探讨 Spring Boot 中 AOP 的执行顺序之前,有必要先了解一些基本概念:

  1. Aspect(切面):切面是切入点和通知(Advice)的组合。它可以理解为一个模块,包含了实现横切关注点逻辑的代码。
  2. Join Point(连接点):程序执行过程中某个特定的点,比如方法调用或异常抛出。
  3. Pointcut(切入点):一组连接点的集合,定义了在哪些连接点上应用通知。
  4. Advice(通知):在切入点上执行的代码。通知有多种类型,包括 Before、After、Around、AfterReturning 和 AfterThrowing。
  5. Weaving(织入):将切面代码应用到目标对象的过程。Spring AOP 使用动态代理进行织入。

AOP 执行顺序

在 Spring AOP 中,不同类型的通知有不同的执行顺序。了解这些顺序对于正确地使用 AOP 非常重要。以下是 Spring AOP 通知的执行顺序:

  1. @Around:环绕通知,围绕目标方法执行。
  2. @Before:前置通知,在目标方法执行前执行。
  3. @AfterReturning:返回通知,在目标方法成功执行后执行。
  4. @AfterThrowing:异常通知,在目标方法抛出异常后执行。
  5. @After:后置通知,在目标方法执行后(无论是否抛出异常)执行。

执行顺序

image.png

执行顺序规则

  1. @Around 通知最先执行,无论目标方法前或后。
  2. @After 通知一定会执行,而 @AfterReturning 和 @AfterThrowing 是二选一。

实战示例

添加依赖

首先,需要在 Spring Boot 项目中添加 AspectJ 依赖:

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
</dependency>

编写切面类

下面是一个示例切面类,定义了各种通知类型,并展示了它们的执行顺序:

@Aspect
@Component
public class HelloAop {

    @Pointcut("execution(* com.example.hello.controller.HelloController.hello(..))")
    public void pointcut() {}

    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        System.out.println("@Before");
    }

    @AfterThrowing("pointcut()")
    public void afterThrowing() {
        System.out.println("@AfterThrowing");
    }

    @AfterReturning("pointcut()")
    public void afterReturning() {
        System.out.println("@AfterReturning");
    }

    @After("pointcut()")
    public void after() {
        System.out.println("@After");
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object result;
        try {
            System.out.println("@Around...方法执行前");
            result = pjp.proceed();
            System.out.println("@Around...方法执行后");
        } catch (Throwable throwable) {
            System.out.println("@Around...抛出异常后");
            throw throwable;
        } finally {
            System.out.println("@Around...finally");
        }
        return result;
    }
}

目标方法

在 HelloController 中添加目标方法:

@RestController
@RequestMapping("/hello")
public class HelloController {

    @GetMapping
    public String hello() {
        System.out.println("目标方法执行");
        return "Hello, AOP!";
    }
}

结果分析

执行 hello 方法时,输出如下:

@Around...方法执行前
@Before
目标方法执行
@Around...方法执行后
@AfterReturning
@After
@Around...finally

由此可以看出,各个通知的执行顺序和逻辑关系。

详细执行过程解析

环绕通知 (@Around)

环绕通知是最先执行的,它围绕目标方法的整个执行过程,包括方法执行前、方法执行后、方法抛出异常后的处理逻辑。环绕通知非常强大,可以用来控制目标方法的执行流程,甚至可以决定是否执行目标方法。

@Around("pointcut()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
    Object result;
    try {
        System.out.println("@Around...方法执行前");
        result = pjp.proceed();
        System.out.println("@Around...方法执行后");
    } catch (Throwable throwable) {
        System.out.println("@Around...抛出异常后");
        throw throwable;
    } finally {
        System.out.println("@Around...finally");
    }
    return result;
}

在上面的代码中,环绕通知在目标方法执行前打印一条消息,然后执行目标方法,并在执行后打印另一条消息。如果目标方法抛出异常,环绕通知会捕获异常并处理它。最后,无论是否发生异常,都会执行 finally 块中的代码。

前置通知 (@Before)

前置通知在目标方法执行前执行,用于执行一些预处理逻辑。

@Before("pointcut()")
public void before(JoinPoint joinPoint) {
    System.out.println("@Before");
}

在上面的代码中,前置通知在环绕通知的目标方法执行前部分之后执行。

返回通知 (@AfterReturning)

返回通知在目标方法成功执行后执行,用于执行一些后处理逻辑。

@AfterReturning("pointcut()")
public void afterReturning() {
    System.out.println("@AfterReturning");
}

在上面的代码中,返回通知在目标方法和环绕通知的目标方法执行后部分之后执行。

异常通知 (@AfterThrowing)

异常通知在目标方法抛出异常后执行,用于执行异常处理逻辑。

@AfterThrowing("pointcut()")
public void afterThrowing() {
    System.out.println("@AfterThrowing");
}

在上面的代码中,如果目标方法抛出异常,异常通知会在环绕通知的异常处理部分之后执行。

后置通知 (@After)

后置通知在目标方法执行后(无论是否抛出异常)执行,用于执行一些最终处理逻辑。

@After("pointcut()")
public void after() {
    System.out.println("@After");
}

在上面的代码中,后置通知在返回通知或异常通知之后执行。

结论

Spring Boot 中 AOP 提供了一种强大的方式来分离和管理应用程序中的交叉关注点。通过理解 AOP 的执行顺序和各类通知的作用,开发者可以更有效地使用 AOP 来实现日志记录、安全性验证、事务管理等功能。

本文通过详细的概念介绍、执行顺序解析和代码示例,帮助您深入理解 Spring Boot 中 AOP 的执行顺序。希望本文能为您的开发工作提供有价值的参考。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值