拦截器逻辑
核心分析DispatcherServlet的doDispatch 方法
-
执行getHandler方法得到HandlerExecutionChain之后,此时方法执行链中已经包装了所有的拦截器
-
在getHandlerAdapter拿到HandlerAdapter 调用适配器的handler方法之前先调用执行链中的PreHandler
-
按序遍历所有的interceptor的调用preHandler方法,如果一旦有preHandler方法返回false,直接进入triggerAfterCompletion方法触发已经执行的Interceptor的afterCompletion方法 返回false跳出执行逻辑
-
每次成功执行之后需要记录当前执行到了哪个interceptor,为了后面逆序执行postHandler和 afterCompletion方法
-
如果返回其中一个interceptor的preHandler方法返回了false,直接触发afterCompletion方法逻辑,本质上就是逆序的for循环,从后往前执行所有的执行器的 afterCompletion方法
-
所有连接器的preHandler方法执行完毕之后,如果返回为true就进入HandlerAdapter的handler方法真正去调用目标方法,如果返回为false,直接 return返回
-
目标方法调用完成之后紧接着调用所有连接器的postHandler
-
进入applyPostHandler方法内部,查看其实也很简单,就是拿到所有拦截器,逆序调用postHandler方法
-
在执行过程中出现任何异常会在外层try被捕获进入catch逻辑调用已经执行过的拦截器的afterCompletion
-
如果没有异常进入processDispatchResult 进行请求分发处理,处理完之后最终还是会调用所有拦截器的afterCompletion
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception { // ... 非核心代码省略 // 渲染 if (mv != null && !mv.wasCleared()) { render(mv, request, response); if (errorView) { WebUtils.clearErrorRequestAttributes(request); } } // .. 非核心代码省略 if (mappedHandler != null) { // 最终处理所有拦截器的afterCompletion mappedHandler.triggerAfterCompletion(request, response, null); } }
-
至此所有拦截器相关逻辑处理结束