拦截器逻辑
核心分析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); } } -
至此所有拦截器相关逻辑处理结束
本文详细分析了Spring MVC中DispatcherServlet的doDispatch方法,探讨了拦截器(Interceptor)的执行流程。在获取HandlerExecutionChain后,拦截器链被创建,每个拦截器的preHandler方法按顺序调用。如果任一preHandler返回false,则会逆序执行afterCompletion方法。当所有preHandler返回true,目标方法被调用,之后再逆序调用postHandler和afterCompletion。整个过程确保了拦截器的正确协调和异常处理。
1026

被折叠的 条评论
为什么被折叠?



