Spring MVC 底层工作流程+源码分析

Spring MVC 底层工作流程+源码分析 Spring MVC 将DispatcherServlet作为前端控制器所有请求都先汇聚于此再由它委派给其他组件协同处理。Spring MVC 核心流程图Spring MVC 核心工作流程含源码关键调用点ViewResolver 视图解析DispatcherServlet 核心调度1. 找处理器2. 返回 HandlerExecutionChain3. 找适配器4. 返回 HandlerAdapter5. 前置拦截若 false 则中断若 true 继续执行业务方法返回 ModelAndView 或直接响应6. 后置拦截7. 处理结果渲染8. 视图解析与渲染9. 最终响应10. 清理资源HTTP Request返回doDispatch 入口getHandler 遍历 HandlerMappinggetHandlerAdapter 获取匹配的 HandlerAdapterapplyPreHandle 执行拦截器 preHandleHandlerAdapter.handle 执行 Controller 方法applyPostHandle 执行拦截器 postHandleprocessDispatchResult 处理结果和异常render 视图渲染triggerAfterCompletion 拦截器 afterCompletionController / RequestMapping 方法resolveViewName 逻辑名 → View 对象View.render 输出 HTML/JSON流程详解对照源码行号步骤角色 / 关键代码位置说明1DispatcherServlet.doDispatch()line 920所有请求入口开始调度。2getHandler()- 遍历handlerMappings通过 URL 找到HandlerExecutionChain含HandlerInterceptor列表。3getHandlerAdapter()根据Handler类型找到能执行它的适配器如RequestMappingHandlerAdapter。4applyPreHandle()依次执行每个拦截器的preHandle方法若返回false则请求短路。5ha.handle()适配器调用实际Controller方法通过反射并封装返回值为ModelAndView。6applyPostHandle()执行拦截器的postHandle方法在Controller之后、视图渲染之前。7processDispatchResult()统一处理ModelAndView或异常。8render()-ViewResolver.resolveViewName()根据逻辑视图名如userList解析出View如InternalResourceView。9View.render()将模型数据与视图合并如 JSP 渲染输出到HttpResponse。10triggerAfterCompletion()执行拦截器的afterCompletion方法无论是否异常最终清理。图中使用了子图DispatcherServlet和ViewResolver并用不同颜色区分组件类型流程箭头清晰标注了步骤序号方便和源码对应。精简版总结一句话 一张表DispatcherServlet 接收请求 → HandlerMapping 定位 → HandlerAdapter 执行 → 拦截器干预 → 返回 ModelAndView → ViewResolver 渲染 → 输出响应阶段组件源码方法接收请求DispatcherServletdoDispatch()定位处理器HandlerMappinggetHandler()执行处理器HandlerAdapterha.handle()视图解析ViewResolverresolveViewName()视图渲染Viewrender()拦截器回调InterceptorpreHandle/postHandle/afterCompletion组件分析核心组件五大关键角色组件职责DispatcherServlet中央调度器接收请求并分发给其他组件HandlerMapping根据请求 URL 找到能处理它的Handler即RequestMapping方法HandlerAdapter适配器确保不同类型的Handler能以统一方式被调用执行ViewResolver根据逻辑视图名如hello解析出真正的View对象如hello.jspView负责视图渲染将Model数据填充到视图中执行流程源码逐步拆解1. 请求入口doDispatch(Request, Response)DispatcherServlet的doDispatch是处理所有请求的核心调度方法protectedvoiddoDispatch(HttpServletRequestrequest,HttpServletResponseresponse)throwsException{HttpServletRequestprocessedRequestrequest;HandlerExecutionChainmappedHandlernull;ModelAndViewmvnull;// ... 上下文设置、异步处理等 ...try{// ✅ 1. 检查文件上传processedRequestcheckMultipart(request);// ✅ 2. 获取处理器执行链 (Handler Interceptors)mappedHandlergetHandler(processedRequest);if(mappedHandlernull){noHandlerFound(processedRequest,response);return;}// ✅ 3. 获取支持该 Handler 的适配器HandlerAdapterhagetHandlerAdapter(mappedHandler.getHandler());// ✅ 4. 执行所有拦截器的 preHandle 方法if(!mappedHandler.applyPreHandle(processedRequest,response)){return;// 如果某个拦截器返回 false流程中断}// ✅ 5. 核心调用 Handler 执行业务逻辑返回 ModelAndViewmvha.handle(processedRequest,response,mappedHandler.getHandler());// ✅ 6. 执行所有拦截器的 postHandle 方法mappedHandler.applyPostHandle(processedRequest,response,mv);// ✅ 7. 最终视图渲染与异常处理processDispatchResult(processedRequest,response,mappedHandler,mv,dispatchException);}catch(Exceptionex){// 统一异常处理}}2. 处理器映射getHandler(Request)以下代码展示了如何为请求找到匹配的处理器protectedHandlerExecutionChaingetHandler(HttpServletRequestrequest){for(HandlerMappinghm:this.handlerMappings){HandlerExecutionChainhandlerhm.getHandler(request);if(handler!null){returnhandler;// 返回包含 Handler 和拦截器链的对象}}returnnull;}3. 获取适配器getHandlerAdapter(Handler)以下代码展示了如何获取适配器protectedHandlerAdaptergetHandlerAdapter(Objecthandler){for(HandlerAdapterha:this.handlerAdapters){if(ha.supports(handler)){returnha;}}thrownewServletException(No adapter for handler...);}4. 业务执行ha.handle(...) - ModelAndView适配器的handle方法内部会解析请求参数与PathVariable执行数据验证与类型转换通过反射调用Controller的具体方法将返回值数据、视图名封装为ModelAndView对象5. 最终响应processDispatchResult(...)processDispatchResult方法会调用ViewResolver将ModelAndView中的逻辑视图名解析为物理视图如 JSP并执行渲染。privatevoidprocessDispatchResult(HttpServletRequestrequest,HttpServletResponseresponse,HandlerExecutionChainmappedHandler,ModelAndViewmv,Exceptionexception)throwsException{// 统一异常处理// ...if(mv!null){// 调用 ViewResolver 解析逻辑视图名render(mv,request,response);}// 执行所有拦截器的 afterCompletion 方法if(mappedHandler!null){mappedHandler.triggerAfterCompletion(request,response,null);}}一个请求进来从前到后的核心处理链就完整走通了DispatcherServlet→HandlerMapping定位方法 →HandlerAdapter适配执行 → 反射调用业务代码返回ModelAndView→ViewResolver与View渲染响应 → 中间穿插着Interceptor的拦截逻辑。将DispatcherServlet类比为公司的前台总机所有访客请求先到这里。总机根据来意查看地图HandlerMapping找到对应部门找到后安排行政助理HandlerAdapter对接业务办完后秘书将结果返回前台再由总机指定专员ViewResolver制作最终的回执文件View交给访客。