
最近刚接触 springboot 切面编程的相关内容,有个问题网上没太找到相关的解答,想问一下家人们~ 我现在定义了一个 @AfterReturning 的方法,在这个方法我执行了一个线程休眠 10 秒的操作。 但是我调用加入这个切点的方法时,为什么是需要调用 10 秒才能返回呀,这个 @AfterReturning 不是在方法执行完成返回结果之后执行的么? 相关代码如下:
@Pointcut("@annotation(com.ice.hilf.contentmoderation.annotation.PicModeration)") public void picPointcut() {} @AfterReturning(pointcut = "picPointcut()", returning = "result") public void doAfterReturning(JoinPoint joinPoint, Object result) throws InterruptedException { System.out.println("Start aop"); // 休眠,等待图片压缩完成 Thread.sleep(10 * 1000); System.out.println("End sleep"); } Controller 层方法上加上切面注解
@PicModeration @PostMapping("/upload") @ResponseBody public ApiResponse<UniFileRtnVO> upload( @RequestParam("file")MultipartFile file, @RequestParam(value = "uploadType", required = false)Byte uploadType, @RequestParam("fileType") Byte fileType){ ... return ApiResponse.success(rtnVO); } 实际测试时结果就是每次调用这个接口要等 10s 才有返回值,是不是我对 @AfterReturning 的执行原理理解的有问题啊
1 BBCCBB 2022 年 6 月 2 日 你 debug 一下, 在你的 afterReturing 里断点, 然后看一下线程执行堆栈. |
2 XhstormR02 2022 年 6 月 2 日 via Android 不是多线程,如果你想让浏览器立即获取接口结果,你应该 hook tomcat 的方法 |
3 iosyyy 2022 年 6 月 2 日 Thread.sleep(10 * 1000); 会挂起当前线程吧 所以不会返回 你新开一个线程用 future 来做异步返回的操作 |
4 iosyyy 2022 年 6 月 2 日 而且你这操作应该用延时队列好一点吧 |
5 LeegoYih 2022 年 6 月 2 日 切面是通过动态代理实现的,可以简单的理解为把代码包了一层,大致执行流程如下: 1. aop.before() 2. res = controller.upload(); 3. aop.after() 4. return res 你在第 3 步睡了 10 秒,HTTP 接口也就会被 block 10 秒,因为他们用的是同一个线程执行的。 |
6 OldCarMan 2022 年 6 月 2 日 个人觉得,spring aop 是通过一个代理对象来完成切面编程的过程的,无论是这个过程的哪个步骤( Around...AfterThrowing )最终都是统一到这个代理对象中的方法一步步去完成这个过程的,这个过程是在同一个线程中完成的,你调用 Thread.sleep(10 * 1000),相当于在这个代理对象的方法中让当前线程休眠 10 秒钟,肯定是无法达到你“方法返回后休眠 10 秒钟”的需求的,简单的话建议使用异步队列的方式去完成你的需求。 |
7 fanxasy 2022 年 6 月 2 日 你想要的是 @After ,不是 @AfterReturning |