DispatcherServlet 请求处理流程与 MVC 组件协作

Spring MVC 建立在 Servlet 之上,它的心脏是一个名为 DispatcherServlet 的前端控制器(Front Controller)。学 MVC 先弄清 DispatcherServlet 的分派流程,后面的映射、拦截器、视图、异常处理才能串成一条线。

什么是前端控制器

所有进入应用的请求先到达 DispatcherServlet,由它把「找处理器、执行处理器、解析视图、渲染响应」等职责委托给各个 MVC 组件,而不是让每个 Controller 自己处理 Servlet 细节。

// 传统 web.xml 时代:所有 URL 都交给 DispatcherServlet(Servlet 3.0+ 可用 Java 方式注册,见第 40 章)
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

一次请求的完整流程(doDispatch)

DispatcherServlet 内部的核心方法是 doDispatch,大致按以下顺序协作:

  1. 设置请求上下文:根据 LocaleResolver、ThemeResolver 解析本地化与主题信息,并放入 LocaleContextHolder 等上下文。
  2. 解析 multipart:若容器中声明了 MultipartResolver 且当前请求是 multipart/form-data,则把请求包装为 MultipartHttpServletRequest。
  3. 找处理器:按注册顺序遍历所有 HandlerMapping,返回 HandlerExecutionChain(处理器 + 匹配的拦截器链)。
  4. 无处理器命中:走 noHandlerFound,默认返回 404(是否抛 NoHandlerFoundException 由配置决定,以官方文档为准)。
  5. 执行 preHandle:按顺序调用链上拦截器的 preHandle,任何一个返回 false 都会短路本次请求。
  6. 执行处理器:选择支持该处理器的 HandlerAdapter,由它解析方法参数并调用 @RequestMapping 方法。
  7. 异步分支:若处理器开启了异步(Callable/DeferredResult),Servlet 容器线程先返回,结果就绪后再次派发。
  8. 执行 postHandle:处理器已返回、视图渲染之前回调。
  9. 处理结果:把 ModelAndView(含逻辑视图名)交给 ViewResolver 解析成 View 并渲染;若抛异常则交给 HandlerExceptionResolver 链。
  10. 收尾:在 finally 中执行 afterCompletion、清理 multipart 临时文件、复位 RequestContextHolder。
请求 → DispatcherServlet → HandlerMapping → HandlerExecutionChain
     → HandlerAdapter → @Controller 方法 → ModelAndView
     → ViewResolver → View 渲染 → 响应
     异常路径:Exception → HandlerExceptionResolver → 错误响应

DispatcherServlet 会探测的组件

DispatcherServlet 启动时会从自身的 WebApplicationContext 中探测一批「特殊 Bean」,缺省时使用内置默认实现:

组件职责无配置时的默认
HandlerMapping请求 URL 映射到处理器RequestMappingHandlerMapping 等(有序)
HandlerAdapter调用处理器、解析参数/返回值RequestMappingHandlerAdapter 等
HandlerExceptionResolver把异常转成响应ExceptionHandlerExceptionResolver 等
ViewResolver逻辑视图名 → View按需配置(默认无)
LocaleResolver解析当前语言区域AcceptHeaderLocaleResolver
ThemeResolver解析主题FixedThemeResolver
MultipartResolver文件上传解析默认无(需要时自行声明)
FlashMapManager重定向传参(Flash 属性)SessionFlashMapManager

多组件并存与优先级

同类型组件可以同时存在多个,例如同时支持注解控制器与静态资源处理器,它们靠 order 排序、由 DispatcherServlet 依次尝试。注解映射的优先级最高,静态资源、默认 Servlet 兜底排在最后,顺序细节以官方文档为准。

DispatcherServlet 把「分发」这件事做得很薄,真正的扩展点都在它委派的组件上:HandlerMapping 决定谁能处理、HandlerAdapter 决定怎么调用、拦截器在调用前后插入逻辑。记住 doDispatch 的这十条顺序,后面的章节都是往这条链上挂东西。

笔记加载中…