先说一下 ,只有单个拦截器的时候的运行流程:(配图是自己的Demo)
当Interceptor 拦截到请求的时候,会执行 preHandle方法,如果这个preHandle方法返回true,就代表这个拦截器放行了,如果返回false,代表这个拦截器不会放行请求
如果放行了这个请求,那么,接下来就会执行目标方法,然后执行这个Interceptor的 postHandler方法,然后目标方法才渲染界面,返回视图模型(ModelAndView),如果没有放行,接下来就不会执行其它的方法了
最后会执行这个Interceptor的afterCompletion方法
接下来说一下有多个拦截器:
假设有两个 拦截器 :
如果第一个 Interceptor 在执行preHandle放法的时候 就没有放行目标的话,那么其它的Interceptor 就都不放行了,接下来的所有方法都不会执行,什么都不会做,
如果第一个Interceptor放行了, 其它 Interceptor 没有放行的话,那么,第一个Interceptor的afterCompletion方法会被调用
多个拦截器情况下的方法的执行顺序:
所有的preHandle方法按顺序执行,postHandle和afterCompletion都逆序执行,具体原因,接下来会分析.
上面是Interceptor的大概运行流程,而接下来,我会在源码上进行分析:
锁定DispatcherServlet类的 doDispatcher 方法,注意打断点的地方:
先看第一个断点,在这个地方,执行了一个叫 applyPreHandle的方法,见名知意,一看就是执行preHandle的方法,这是这个方法的源码:
不用细看,只需要注意在这里面有一个 for循环,并且这个 for 循环是按照顺序执行的,这个for循环里干的事情就是按顺序执行所有的 Interceptor的 preHandle方法,如果这个方法执行失败,就直接结束整个doDispatcher方法的运行,这就可以验证了我上面所说的,如果一旦第一个preHandle方法运行失败,也就是第一个拦截器都不放行的话,后面的流程都没法继续走了,如果第一个preHandle方法放行了,第二个没有放行,那么也会继续走下去
再看第二个断点:
这里就不用细说了,就是执行目标方法,也验证了 我上面说的 执行完 preHandle方法后,就会执行目标方法,如果第一个preHandle方法放行了,第二个方法没有放行,那么也会执行到这个目标方法
第三个断点:
这里也是见方法名知意:执行 postHandle方法,也是如上所说,只要放行了,这个方法铁定会被执行,这是这个方法的源码:
它的作用就是 逆序执行 所有已放行了的Interceptor的 postHandler 方法的
和接下来看这个3个断点:
先是处理了 ModelAndView 的结果,然后在 2 个catch 语句里 有两个 triggerAfterCompletion方法,
先不管这个这个方法是什么意思,首先,既然是在catch语句里,那么 铁定是出现异常才会执行的方法,对吧,ok
先看最后一个断点:
首先这个方法就是在finally里面的,最后try cath 里面的内容结束的时候就会执行这个finally块里面的
代码,最后再看 triggerAfterCompletion 方法和 这最后一个断点方法的作用:
这是triggerAfterCompletion 方法的源码:
同样,这个方法里也有 for循环,并且是 逆序 的,它的作用就是 逆序 执行所有Interceptor的 afterCompletion 方法的
这是tapplyAfterConcurrentHandlingStarted方法的源码:
可以看到这个方法的源码和 上面那个方法的源码非常相似,由此可推出,这个方法也是逆序执行
所有已放行了的Interceptor 的 afterCompletion 方法的
综上可知, triggerAfterCompletion 方法 和 applyAfterConcurrentHandlingStarted方法都是执行afterCompletion 的,但是两个方法的位置不同,所以决定了它们的运行的时机不同,也就是我所说的,如果,第一个Interceptor 就放行了, 那么 这个方法的 afterCompletion 就会被执行,不管第二个,第三个,,,等等的Interceptor放行没有.
因为个人能力有限,语言表述不清楚的话,请同学原谅,谢谢。。。。