Spring Boot Aop执行顺序深入探究

 更新时间:2024年01月21日 09:57:12   作者:冯文议  
这篇文章主要为大家介绍了Spring Boot Aop执行顺序深入探究,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

Spring Boot Aop 执行顺序

1. 概述

在 spring boot 项目中,使用 aop 增强,不仅可以很优雅地扩展功能,还可以让一写多用,避免写重复代码,例如:记录接口耗时,记录接口日志,接口权限,等等。所以,在项目中学习并使用 aop ,是十分必要的。然而,当我们在一个接口中使用多个 aop,时,就需要注意他们的执行顺序了。那么,它们的执行顺序是怎样的呢?如果不把这个问题搞明白,那我们的程序就不可控,这是不允许的,这就是我们今天要讨论的问题。

2. 实现 AOP

2.1 通过注解实现 AOP

MyAop:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAop {
}

MyAspect:

@Aspect
@Component
public class MyAspect {

    @Around("@annotation(aop)")
    public Object around(ProceedingJoinPoint joinPoint, 
                         MyAop aop) throws Throwable {
        return joinPoint.proceed();
    }

}

SampleController#myApi:

@RestController
@RequestMapping("/sample")
public class SampleController {
    @MyAop
    @RequestMapping("/my-api")
    public String myApi() {
        return "success";
    }
}

这样,我们就通过使用注解的方式实现了 AOP 。

2.2 通过扫描包

比如,我们有这样一个接口 SampleController#myApi2:

@RestController
@RequestMapping("/sample")
public class SampleController {

    @RequestMapping("/my-api2")
    public String myApi2() {
        return "success";
    }

}

我们可以使用包扫描的方式进行拦截:

@Aspect
@Component
public class My2Aspect {

    @Around("execution(* com.fengwenyi.demo.springboot.aop.controller.SampleController.myApi2(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        return joinPoint.proceed();
    }

}

这样,我们也就通过使用包扫描的方式实现了 AOP 。

3. 多个 AOP

3.1 分析

先提一个疑问:多个AOP注解,执行顺序是怎么样的呢?如何设置执行顺序呢?

比如,APP 请求我们的 API 接口,在请求到达 API 接口之前,可以先执行 AOP1,在执行 AOP2,并且顺序不能变,如下图:

我们再拆解一下实际内部执行逻辑。

请求:请求先进入到 AOP1,再进入到 AOP2,最后到达 API。

返回:执行完 API,再回到 AOP2,最后回到 AOP1。

如下图:

因为我们用的是 Around,先进入Aop1,再进入到aop2,然后执行api,执行完以后,再返回到 aop2,最后返回aop1。

3.2 代码实现

MyFirstAop:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyFirstAop {
}

MyFirstAspect:

@Slf4j
@Aspect
@Component
@Order(100002)
public class MyFirstAspect {
    @Around("@annotation(aop)")
    public Object around(ProceedingJoinPoint joinPoint, 
                         MyFirstAop aop) throws Throwable {
        log.info("MyFirstAspect#around execute start");
        try {
            return joinPoint.proceed();
        } finally {
            log.info("MyFirstAspect#around execute end");
        }
    }
}

MySecondAop:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface MySecondAop {
}

MySecondAspect:

@Slf4j
@Aspect
@Component
@Order(100003)
public class MySecondAspect {
    @Around("@annotation(aop)")
    public Object around(ProceedingJoinPoint joinPoint, 
                         MySecondAop aop) throws Throwable {
        log.info("MySecondAspect#around execute start");
        try {
            return joinPoint.proceed();
        } finally {
            log.info("MySecondAspect#around execute end");
        }
    }
}

SampleController#aopOrder:

@RestController
@RequestMapping("/sample")
public class SampleController {

    @MySecondAop
    @MyFirstAop
    @RequestMapping("/aop-order")
    public String aopOrder() {
        return "aopOrder";
    }

}

通过设定 Order 值,指定 AOP 执行顺序,与我们的期望一致。

好了,今天的分享就到这里了,源码:demo-spring-boot-aop

以上就是Spring Boot Aop 执行顺序的详细内容,更多关于Spring Boot Aop 执行顺序的资料请关注脚本之家其它相关文章!

相关文章

  • Java中BigDecimal类的add()的使用详解

    Java中BigDecimal类的add()的使用详解

    这篇文章主要介绍了Java中BigDecimal类的add()的使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 详解使用spring boot admin监控spring cloud应用程序

    详解使用spring boot admin监控spring cloud应用程序

    这篇文章主要介绍了详解使用spring boot admin监控spring cloud应用程序,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • @RequestParam 和@RequestBody注解的区别解析

    @RequestParam 和@RequestBody注解的区别解析

    在 Spring MVC 中,我们可以使用 @RequestParam 和 @RequestBody 来获取请求参数,但它们在用法和作用上有一些区别,这篇文章主要介绍了@RequestParam 和@RequestBody注解的区别,需要的朋友可以参考下
    2023-06-06
  • IDEA搭建SpringBoot离线工程的方法

    IDEA搭建SpringBoot离线工程的方法

    这篇文章主要介绍了IDEA搭建SpringBoot离线工程的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-06-06
  • Java web velocity分页宏示例

    Java web velocity分页宏示例

    这篇文章主要介绍了Java web velocity分页宏示例,需要的朋友可以参考下
    2014-03-03
  • java 中堆内存和栈内存理解

    java 中堆内存和栈内存理解

    这篇文章主要介绍了java 中的堆内存和栈内存的知识,有需要的朋友可以参考下
    2017-03-03
  • 解读Jvm的内存结构与GC及jvm参数调优

    解读Jvm的内存结构与GC及jvm参数调优

    这篇文章主要介绍了解读Jvm的内存结构与GC及jvm参数调优方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • 浅析Spring 中 Bean 的理解与使用

    浅析Spring 中 Bean 的理解与使用

    这篇文章主要介绍了Spring 中 Bean 的理解与使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-03-03
  • 深入了解Java设计模式之职责链模式

    深入了解Java设计模式之职责链模式

    Java设计模式中有很多种类别,例如单例模式、装饰模式、观察者模式等。本文将为大家详细介绍其中的职责链模式,感兴趣的可以了解一下
    2022-09-09
  • 详解Java中final的用法

    详解Java中final的用法

    本文主要介绍了Java中final的使用方法,final是java的关键字,本文就详细说明一下它的使用方法,需要的朋友可以参考下
    2015-08-08

最新评论