SpringBoot请求处理流程

Spring中的拦截器有三个函数,我们先给他们起个名字,方便称呼。

  1. preHandle 前置拦截
  2. postHandle 后置拦截
  3. afterCompletion 完成拦截

正常流程

DispatcherServlet#doDispatch

请求处理流程可以参照DispatcherServlet的doDispatch方法。将其简化如下:

public void doDispatch() {
        try {
            try {
                getHandler();//获取拦截器和处理器
                applyPreHandle();//触发前置拦截
                handle();//执行处理方法
                applyPostHandle();//触发后置处理
            } catch (Exception e) {}
            //处理异常,同时触发完成拦截
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        } catch (Exception e) {
        	//触发完成拦截
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
        } 
    }

可以看到,主要有两个try块。内部的try是对 前置处理–Controller处理–后置处理 进行异常捕获,进行全局异常处理。外部的try是为了捕获全局异常处理方法中抛出的异常。完成拦截是由 HandlerExecutionChain 执行的,它在执行的时候进行了try()catch, 如下图,所以完成拦截的异常不会被抛出。
在这里插入图片描述

流程图

流程图

有三点需要注意:

  1. 注意执行顺序。前置拦截是正序,后置拦截和完成拦截是倒序。
  2. 这是在前置拦截全都返回true的情况下的流程图。如果某一个前置拦截返回false,流程图如下图所示。
  3. ExceptionResolver代表我们自己实现HandlerExceptionResolver的类,或者在@ControllerAdvice中生命的@ExceptionHandler
    preHandle返回false

异常流程

异常发生在preHandle

如果异常发生在前置拦截器,那么就会跳出内部的try块,进入 processDispatchResult 函数,这个函数负责拦截全局异常,并执行拦截器的 afterCompletion 函数。所以此时的处理流程如下图。表示第二个拦截器的 preHandle 发生异常,注意第二个拦截器的 afterCompletion 不会执行,只有绿色的部分会执行。
异常发生在preHandle

异常发生在处理器

异常发生在处理器

异常发生在postHandle

异常发生在postHandle

异常发生在全局异常处理器

上面说到,在 processDispatchResult 函数中会执行全局异常处理,如果这里出现异常,就会跳进外部的catch,触发拦截器的 afterCompletion 。此时的流程为:
异常发生在全局异常处理器

异常发生在afterCompletion

拦截器的 afterCompletion 被try()catch包裹了,所以异常会被捕获,然后继续执行下一个拦截器的 afterCompletion 。如下图:
异常发生在afterCompletion

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值