假设目前配置两个拦截器
设置FirstIntercetpor关闭拦截
设置SecondInterceptor打开拦截
我们来执行,结果如下
根据结果我们可以得出结论, FirstIntercetpor执行了preHandle,afterCompletion
SecondInterceptor执行preHandle
接着找源码在DispatchServelet中找到doDispatch中applyPreHandle,该方法负责处理preHandle
我们点进去
此处是关键
我们来看debug数据,接下来我们要一步一步debug查看相关信息
第一步这里我们看到此处的拦截器并非我们配置的拦截器,为系统默认,无关紧要
我们几次f8跳过,然后再f7跳入,此处的拦截器依然不是我们配置的,继续进行
重点来了
看这里,这一次执行到了第三拦截器,这个是我们配置的FirstIntercetpor拦截器,我们注意这里的执行过程
一次f7,这里到了我们配置的拦截器内部开始执行我们的拦截器preHandle方法
这里我们的返回值为true,因此红线部分条件不成立,我们不执行if语句,进入下一个循环
下一个循环我们进入了我们配置的SecondInterceptor拦截器的preHandle方法
我们继续进行,这一次返回值为false,加上前面的!号,双重否定即肯定,我们这一次开始执行if方法
我们注意到这个if语句中唯一的方法triggerAfterCompletion,这个就是处理我们AfterCompletion方法的,我们进入这个方法内部
重点来了,这里的拦截器来看一下,是FirstIntercetpor拦截器,那么这里将要执行的方法自认就是FirstIntercetpor拦截器的afterCompletion
那么问题来了,为什么这里找到的是FirstIntercetpor
我们再次回到之前的方法
这里面有一个叫interceptorIndex的参数
这个参数是dispatchservelet的公共参数,
在我们的applyPreHandle跟afterCompletion都有调用
在执行之前的applyPreHandle方法中,这个数字是从0开始依次加一,直到满this.interceptorList.size(),
而+1的前提就是if方法不执行,if方法不执行的前提是取到拦截器的PreHandle方法返回值为true,前面三个拦截器都放行,所以interceptorIndex增长到了2,
到SecondInterceptor拦截器的时候,他PreHandle返回值为false,执行if方法,interceptorIndex不增长,
而triggerAfterCompletion中的循环是从interceptorIndex递减到0,那么自认不会执行SecondInterceptor拦截器的afterCompletion方法
执行完triggerAfterCompletion,applyPreHandle执行结束,返回false
我们接着看
applyPreHandle返回false那么if语句就成立,dodispatch方法执行结束
后面的
视图渲染方法
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
视图加载方法
this.applyDefaultViewName(processedRequest, mv);
传递信息方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
运行处理结果方法
his.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
自然统统不执行,自此拦截过程结束