SpringMVC 工作原理
SpringMVC 是 Spring 框架中用于构建 Web 应用的核心模块,其工作流程围绕 “前端控制器(DispatcherServlet)” 展开,通过组件间的协作完成请求处理与响应。理解其工作原理是掌握 SpringMVC 开发的关键,以下将通过 核心组件解析、详细工作流程(含步骤拆解与流程图解) 两部分进行说明。
SpringMVC 核心组件
在了解流程前,需先明确参与请求处理的核心组件及其职责,各组件通过 Spring 容器管理,由 DispatcherServlet 调度。
组件名称 | 核心职责 |
---|---|
DispatcherServlet | 前端控制器(核心),统一接收所有请求,协调其他组件完成处理,避免组件耦合。 |
HandlerMapping | 处理器映射器,根据请求 URL 找到对应的 Handler(处理器,如 Controller 方法),返回 Handler 及拦截器链。 |
HandlerAdapter | 处理器适配器,适配不同类型的 Handler(如注解式 Controller、XML 配置的 Controller),调用 Handler 的业务方法。 |
Handler(处理器) | 业务逻辑处理器,即开发者编写的 Controller 类(或方法),负责处理具体业务逻辑。 |
ModelAndView | 处理器返回的结果对象,包含 Model(数据模型,如请求处理后的业务数据) 和 View(视图名称,如 JSP 路径)。 |
ViewResolver | 视图解析器,根据 ModelAndView 中的视图名称,解析为实际的 View 视图对象(如 JSP 文件、HTML 页面)。 |
View(视图) | 渲染视图,将 Model 中的数据填充到视图模板(如 JSP),生成最终的 HTML 响应给客户端。 |
Interceptor | 拦截器,可在请求处理的 预处理(前)、后处理(后)、完成处理(最终) 阶段插入自定义逻辑(如登录校验、日志记录)。 |
SpringMVC 完整工作流程(10 步拆解)
SpringMVC 的工作流程本质是 “DispatcherServlet 主导的组件协作流程”,从客户端发送请求到接收响应,共分为 10 个核心步骤,流程如下:
1. 流程步骤拆解
- 客户端发送 HTTP 请求
用户通过浏览器、Postman 等工具发送请求(如http://localhost:8080/springmvc/user/list
),请求被 Web 服务器(如 Tomcat)接收。 - 请求被 DispatcherServlet 拦截
Web 服务器根据web.xml
(或 SpringBoot 自动配置)中配置的DispatcherServlet
映射规则(如/
拦截所有请求,排除静态资源),将请求转发给 DispatcherServlet(前端控制器)。 - DispatcherServlet 调用 HandlerMapping
DispatcherServlet 不直接处理请求,而是调用 HandlerMapping(处理器映射器),根据请求 URL、请求方法(GET/POST)等信息,查找对应的 Handler(如 Controller 中的listUser()
方法),同时返回该 Handler 对应的 拦截器链(Interceptor Chain)。 - DispatcherServlet 获取 HandlerAdapter
DispatcherServlet 根据 Handler 的类型(如注解式@Controller
、实现Controller
接口的类),调用对应的 HandlerAdapter(处理器适配器),确保后续能统一调用 Handler 的业务方法。 - 执行拦截器的预处理方法(preHandle)
若存在拦截器,DispatcherServlet 会先执行拦截器链中所有拦截器的preHandle()
方法。- 若任意一个拦截器的
preHandle()
返回false
,则请求终止,直接返回响应(可用于登录校验失败的场景); - 若全部返回
true
,则继续执行后续流程。
- 若任意一个拦截器的
- HandlerAdapter 调用 Handler 业务方法
HandlerAdapter 调用 Handler(Controller 方法)的业务逻辑,处理请求(如查询数据库、处理参数),最终返回 ModelAndView 对象(包含业务数据 Model 和视图名称 ViewName,如ModelAndView("user/list", "users", userList)
)。 - 执行拦截器的后处理方法(postHandle)
Handler 执行完成后,DispatcherServlet 会倒序执行拦截器链中所有拦截器的postHandle()
方法(此时 ModelAndView 已生成,可在此处修改视图或数据)。 - DispatcherServlet 调用 ViewResolver 解析视图
DispatcherServlet 将 Handler 返回的 ModelAndView 传递给 ViewResolver(视图解析器),ViewResolver 根据视图名称(如user/list
)和配置的视图前缀(如/WEB-INF/views/
)、后缀(如.jsp
),解析为实际的 View 视图对象(如/WEB-INF/views/user/list.jsp
)。 - View 渲染视图并返回响应
View 视图对象结合 Model 中的数据(如users
列表),渲染生成 HTML 页面(将数据填充到 JSP 模板的标签中),并将渲染后的响应结果返回给 DispatcherServlet。 - 执行拦截器的完成处理方法(afterCompletion)
响应返回前,DispatcherServlet 会倒序执行拦截器链中所有拦截器的afterCompletion()
方法(无论请求是否成功,均会执行,可用于资源释放,如关闭流)。最终,DispatcherServlet 将响应结果返回给客户端(浏览器),流程结束。
2. 工作流程流程图(文字示意)
客户端(浏览器)
↓ 1. 发送HTTP请求
Web服务器(Tomcat)
↓ 2. 转发给DispatcherServlet(根据映射规则)
DispatcherServlet(前端控制器)
↓ 3. 调用HandlerMapping
HandlerMapping(处理器映射器)
↓ 返回:Handler + 拦截器链
DispatcherServlet
↓ 4. 匹配HandlerAdapter
HandlerAdapter(处理器适配器)
↓ 5. 执行拦截器preHandle()(全部true则继续)
↓ 6. 调用Handler(Controller方法)→ 返回ModelAndView
↓ 7. 执行拦截器postHandle()(倒序)
DispatcherServlet
↓ 8. 调用ViewResolver解析视图
ViewResolver(视图解析器)
↓ 返回:实际View对象(如JSP)
↓ 9. View渲染(Model数据填充到View)→ 生成HTML
↓ 10. 执行拦截器afterCompletion()(倒序)
DispatcherServlet
↓ 返回响应
客户端(浏览器)
关键总结
- DispatcherServlet 是 “中枢”:所有请求都经过它,负责协调 HandlerMapping、HandlerAdapter、ViewResolver 等组件,降低组件耦合。
- 组件职责单一:每个组件只做一件事(如 HandlerMapping 只负责找 Handler,ViewResolver 只负责解析视图),符合 “单一职责原则”。
- 拦截器作用于流程节点:通过
preHandle
、postHandle
、afterCompletion
可在请求处理的关键节点插入自定义逻辑,增强灵活性。 - ModelAndView 是 “数据 + 视图” 载体:Handler 不直接渲染视图,而是返回 ModelAndView,由 ViewResolver 和 View 完成渲染,实现 “业务逻辑与视图分离”。