首页 > 其他分享 >SpringAop使用

SpringAop使用

时间:2022-08-24 10:58:30浏览次数:47  
标签:advice System println 使用 SpringAop 执行 方法 out

此文章直接进入aop的使用,aop的相关概念请自行补:

推荐链接: https://blog.csdn.net/q982151756/article/details/80513340

 

进入正题。

Advice 的5种类型:

 

  1. before advice, 在 join point 前被执行的 advice. 虽然 before advice 是在 join point 前被执行, 但是它并不能够阻止 join point 的执行, 除非发生了异常(即我们在 before advice 代码中, 不能人为地决定是否继续执行 join point 中的代码)。
  2. after return advice, 在一个 join point 正常返回后执行的 advice。
  3. after throwing advice, 当一个 join point 抛出异常后执行的 advice。
  4. after(final) advice, 无论一个 join point 是正常退出还是发生了异常, 都会被执行的 advice.。
  5. around advice, 在 join point 前和 joint point 退出后都执行的 advice. 这个是最常用的 advice.

 

实例代码:

一:前置通知: @Before

1、先建一个切面类,声明切入点,写前置通知逻辑。

@Aspect
@Component
public class AspectTest {
    //切入点
    @Pointcut("execution(* com.tan.controller..*(..))")
    public void testAspect() {

    }
    @Before(value = "testAspect()")
    public void before() {
        System.out.println("前置通知");
    }
}

测试代码,后续都是调这个接口测试:

    @GetMapping("/aop")
    public String aopTest(String id,String name) {
        //System.out.println("请求参数:"+id+",name:"+name);
        System.out.println("this is method");
        //int a = 10 / 0;
        return "这是方法执行的返回结果";
    }

运行结果:

 

 

 二:后置通知:@AfterReturning

   @AfterReturning(value = "testAspect()")
    public void afterReturning() {
        System.out.println("方法执行后而且没有异常后的通知");
    }

 

 

 三:异常通知 : @AfterThrowing

  @AfterThrowing(value = "testAspect()")
    public void afterThrowing() {
        System.out.println("异常后通知");
    }
@GetMapping("/aop")
public String aopTest(String id,String name) {
//System.out.println("请求参数:"+id+",name:"+name);
System.out.println("this is method");
int a = 10 / 0;
return "aop";
}
 

 

 

 四:最终通知 :@After

@After(value = "testAspect()")
public void after(JoinPoint joinPoint) {
System.out.println("后置通知");
}

 

 

 五:环绕通知:@Around

    @Around(value = "testAspect()")
    public Object test(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕通知: 方法前,test先执行了");
        //环绕通知=前置+目标方法执行+后置通知,proceed方法就是用于启动目标方法执行的.
        //确实是order越小越是最先执行,但更重要的是最先执行的最后结束
        //Thread.sleep(5000);
        Object s = proceedingJoinPoint.proceed();
        // System.out.println("方法名:" + proceedingJoinPoint.getSignature());
        // System.out.println("方法参数+"+ Arrays.toString(proceedingJoinPoint.getArgs()));
        //System.out.println("s是: " + s);
        System.out.println("环绕通知: 方法后");
        return "";
    }

 

 

 

ProceedingJoinPoint 类的一些常用方法:
//启动目标方法执行 :proceedingJoinPoint.proceed()
Object s = proceedingJoinPoint.proceed();
//获取方法名:proceedingJoinPoint.getSignature()
System.out.println("方法名:" + proceedingJoinPoint.getSignature());
//获取方法参数:proceedingJoinPoint.getArgs()
System.out.println("方法参数:" + Arrays.toString(proceedingJoinPoint.getArgs()));

 

 

spring 多个切面的执行顺序及原理:

https://blog.csdn.net/qq_32317661/article/details/112310508

直接总结:

这里用注解的方式:在类上加上  @Order(1)

order越小越是最先执行,但更重要的是最先执行的最后结束。

这个不难理解,Spring AOP就是面向切面编程,什么是切面,画一个图来理解下:

 

 

 

由此得出:spring aop就是一个同心圆,要执行的方法为圆心,最外层的order最小。从最外层按照AOP1、AOP2的顺序依次执行doAround方法,doBefore方法。然后执行method方法,最后按照AOP2、AOP1的顺序依次执行doAfter、doAfterReturn方法。也就是说对多个AOP来说,先before的,一定后after。

如果我们要在同一个方法事务提交后执行自己的AOP,那么把事务的AOP order设置为2,自己的AOP order设置为1,然后在doAfterReturn里边处理自己的业务逻辑。

总结:

如果两个切面中覆写的getOrder方法中返回的是0,就是还没有显式的指定不同的顺序,所以,根据跟踪源码,可以发现在order相同的情况下, 是根据切面类的名称字母序进行优先级控制的,字母序越靠前,优先级越高。字母序的比较,首先将类名转换为字符串,然后调用String的compareTo()方法,对两个类名进行比对,决定切面的排序的。如果切面类使用了@Order注解或者是实现了Ordered接口,那么可以在比对的时候自动调用getOrder()的方法,然后比较返回的值大小,值越小,优先级越高。

同一个切面类中的方法,如果有多个不同的切入方式,例如@Around,@Before,@After,@AfterReturning,@AfterThrowing,那么会先扫描出各个方法上的注解,对不同的方法按照上边注解的顺序进行排序,然后按照字母序进行排序,所以最终呈现出来的,同一个切面类中的不同切面方法的执行顺序,就会呈现如上所示的状态。

 

标签:advice,System,println,使用,SpringAop,执行,方法,out
From: https://www.cnblogs.com/dragon-lan/p/16619051.html

相关文章

  • 1.1 File类的简单使用
    File类的使用在学习File类之前,我们需要知道一个知识点的概念、有什么用、需要掌握的东西以及学完后我能做出什么东西出来等。所以后面的章节也会以这几个点来作为主要的......
  • 36. Redis---Java使用Redis
    1.前言在开始学习本节内容之前,首先需要您掌握Java编程语言,其次确定您已经安装了Redis服务及JavaRedis驱动,并且能够成功运行Java程序。本节介绍如何在Java中......
  • 视图解析器的使用
     目前web应用都是使用前后端分离的开发方式,在这种方式下,其实不会用到springmvc的视图解析器。官网上有这么一段话:Anappropriatehandlerissearchedfor.Ifahandler......
  • vue3+ts使用bus事件总线
    1、在vue2中我是这样使用的//创建一个vueBus.jsimportBusfrom'vue';letinstall=function(Vue){Vue.prototype.$bus=newBus()}exportdefault{install};......
  • Python-Anaconda介绍、安装及使用教程
    〇、序一、什么是Anaconda?1.简介2.特点3.Anaconda、conda、pip、virtualenv的区别①Anaconda②conda③pip④virtualenv⑤pip与conda比较→依赖......
  • 解决windows10虚拟桌面不能换桌面的问题--使用软件SylphyHorn
    GitHub:https://github.com/Grabacr07/SylphyHornwindows应用商店:https://apps.microsoft.com/store/detail/sylphyhorn/9NBLGGH58T01?hl=en-us&gl=US软件截图:效果......
  • esp32使用lvgl界面来控制四线散热风扇
    参考这位同学的文章  esp82664线风扇调速测速|OldGerman'sBlogesp32是3.3v的单片机io口可以忍受5v电平  所以如果接普通的电脑上5v的风扇不需要电平转换,加上......
  • IDEA2021.1.2版本使用Git解决代码冲突
    一、push时遇到冲突当前分支主管的推送被拒绝推送前需要合并远程更改   当前分支主管的推送被拒绝  推送前需要合并远程更改  当push时遇到冲突,要先pul......
  • IDEA2021.1.2版本使用Git
    IDEA中类的颜色红色:工作区已修改并未添加到暂存区绿色:修改已经添加到暂存区暂未提交到版本库黑色|白色:版本库与工作区一致nothingtocommit,workingtreeclea......
  • [Android开发学iOS系列] 工具篇: Xcode使用和快捷键
    [Android开发学iOS系列]工具篇:Xcode使用和快捷键工欲善其事必先利其器.编辑Cmd+N:新建文件Option+Cmd+N:新建文件夹Cmd+/:注释Ctrl+I:formatind......