一、什么是SpringMVC
之前一直觉得会使用框架就懂了,但其实底层原理我们也要清楚,这样使用的时候就会更加有逻辑,而不是只停留在表面
SpringMVC是Spring生态体系内置的MVC分层Web请求处理框架 ,底层基于原生Servlet规范实现,核心入口为DispatcherServlet中央调度器。 它专门用于服务端接收HTTP请求、参数绑定、调用业务层、封装返回结果,是传统SSM框架、现代SpringBoot后端接口开发的Web底层支撑,所有SpringBoot Web接口本质底层都在运行SpringMVC。
MVC三层拆分含义:
- Model(模型):封装业务数据、数据库查询结果,对应项目中的Service、DAO、实体类;
- View(视图):页面展示层,如JSP、Thymeleaf、HTML模板;前后端分离项目几乎舍弃视图层,统一返回JSON;
- Controller(控制器) :接收前端请求,协调Model与View,处理请求分发逻辑,开发者编写的
@RestController/@Controller即为控制器。
二、SpringMVC核心特点与优势
1. 基于注解开发,无强制类继承约束
原生Servlet开发必须继承HttpServlet重写doGet/doPost方法,耦合度极高; SpringMVC仅通过@Controller、@RestController标记普通POJO类即可作为控制器,无需继承任何框架类、实现接口,代码轻量化、低耦合。
2. 分层解耦,职责单一
整套框架拆分多个独立组件:调度器、处理器映射器、处理器适配器、视图解析器,每个组件只负责一件事,符合单一职责原则,组件可灵活替换扩展。
3. 原生支持RESTful接口规范
提供@GetMapping、@PostMapping、@PutMapping、@DeleteMapping系列注解,天然支持REST风格接口设计,搭配@RestController快速实现前后端分离JSON返回。
4. 内置拦截器机制,统一请求增强
提供HandlerInterceptor拦截器,可在Controller执行前后、请求结束后自定义逻辑,用于登录校验、权限拦截、日志记录,区别于Servlet过滤器Filter,仅作用于SpringMVC内部请求。
5. 强大的参数自动绑定与类型转换
前端表单、URL路径参数、JSON请求体,框架自动封装到实体类,自动完成字符串、数字、日期等类型转换,无需手动通过request.getParameter()取值。
6. 容器统一管理,依托Spring IOC
所有Controller、拦截器、工具组件都交由Spring IOC容器管理,自动实现依赖注入,Controller可直接注入Service、Mapper,无需手动创建对象。
7. 灵活的视图解析机制
内置InternalResourceViewResolver视图解析器,自动拼接页面前缀后缀,传统服务端渲染项目可快速跳转页面;前后端分离场景直接跳过视图解析,序列化对象返回JSON。
三、核心组件对应图讲解(结合流程图)

图片来源于网络
先梳理图中全部核心组件,明确每个组件定位:
- DispatcherServlet(中央调度器) :SpringMVC总入口,所有HTTP请求第一道关口,全局总指挥;本质是
HttpServlet子类,底层依托Servlet运行。 - HandlerMapping 处理器映射器:只做查询工作,根据请求URL匹配对应Controller方法,封装成处理器执行链返回。
- HandlerExecutionChain 处理器执行链:封装目标Handler(Controller方法)+ 全部拦截器集合,类比过滤器链。
- HandlerAdapter 处理器适配器:统一执行规范,适配不同类型Controller,真正调用Controller业务方法。
- Handler(Controller) 处理器:开发者编写的接口业务类,调用Service操作数据库。
- ModelAndView:封装Controller返回的数据(Model)与视图名称(View),前后端分离项目不会生成该对象。
- ViewResolver 视图解析器:拼接页面路径,定位前端视图文件。
- View 视图:页面模板,渲染数据并生成最终页面返回浏览器。
四、基于流程图的完整11步执行流程
步骤1:浏览器发起HTTP请求
前端通过URL发送GET/POST/PUT/DELETE请求,请求抵达服务端,首先进入DispatcherServlet中央调度器。
补充:SSM需要在web.xml手动注册DispatcherServlet;SpringBoot通过自动配置
WebMvcAutoConfiguration自动创建注册,无需XML配置。
步骤2:DispatcherServlet调用HandlerMapping处理器映射器
调度器将当前请求交给HandlerMapping,核心作用:解析当前请求URL,扫描项目中所有Controller,匹配该URL对应的目标业务方法。
步骤3:HandlerMapping返回HandlerExecutionChain执行链
匹配完成后,映射器返回一条执行链,包含两部分:
- Handler:目标Controller方法;
- 拦截器数组:当前请求需要执行的所有Interceptor拦截器。
步骤4:DispatcherServlet调用HandlerAdapter处理器适配器
调度器拿到执行链后,不直接执行Controller,交给适配器。 设计适配器的原因:SpringMVC支持多种类型控制器(注解Controller、传统Controller),适配器统一封装调用逻辑,调度器无需关心Controller底层实现。
步骤5:HandlerAdapter调用目标Handler(Controller)
适配器按照统一反射逻辑,执行匹配到的Controller接口方法,自动完成请求参数封装、类型转换。
步骤6:Controller调用Service、DAO操作数据库
控制器执行业务逻辑,调用Service层处理业务,DAO层查询/修改数据库,拿到业务结果数据。
步骤7:Controller返回ModelAndView对象
- 传统服务端渲染(JSP/Thymeleaf) :方法返回数据+视图名称,封装为
ModelAndView;Model存放页面所需数据,View代表页面文件名。 - 前后端分离项目(@RestController) :方法添加
@ResponseBody,直接返回实体对象、字符串,框架使用Jackson自动序列化为JSON,不会生成ModelAndView,直接跳过视图解析流程。
步骤8:DispatcherServlet调用ViewResolver视图解析器
仅传统页面项目会执行此步骤;调度器将ModelAndView交给视图解析器,自动拼接页面前缀、后缀,找到服务器存放的真实视图文件。 例:视图名为user,前缀/templates/,后缀.html,最终定位/templates/user.html。
步骤9:视图解析器返回View视图对象
解析完成后,返回封装好路径的视图对象。
步骤10:View执行视图渲染
框架将Model中存储的业务数据填充到HTML/JSP页面,完成页面渲染,生成完整静态页面。
步骤11:DispatcherServlet向前端返回HTTP响应
- 页面项目:将渲染完成的HTML页面作为响应返回浏览器;
- 前后端分离项目:直接返回JSON字符串,无视图渲染步骤。
五、流程关键补充知识点(面试高频拓展)
1. 拦截器Interceptor执行时机(内嵌在执行链中)
一条完整请求中拦截器执行顺序:
preHandle:Controller执行前,返回false直接拦截请求,流程终止;postHandle:Controller执行完毕,视图渲染之前;afterCompletion:整个请求全部结束,资源释放、日志记录。
拦截器属于SpringMVC自有组件,仅DispatcherServlet内部生效;Filter过滤器属于Servlet原生规范,先执行Filter,再进入DispatcherServlet,最后执行拦截器。
2. HandlerMapping与HandlerAdapter的分工区别
- HandlerMapping:只负责查找,根据URL找到Controller,不执行任何业务代码;
- HandlerAdapter:只负责执行,统一调用Controller方法,不做匹配查找。
3. @Controller 和 @RestController 对流程的影响
@Controller:无自动JSON转换,方法返回字符串会进入视图解析流程,跳转页面;如需返回JSON,方法上加@ResponseBody;@RestController = @Controller + @ResponseBody:类内所有方法自动序列化对象为JSON,直接跳过步骤8、9、10,不执行视图渲染,适配前后端分离开发。
4. url-pattern / 和 /* 的区别
SSM配置DispatcherServlet拦截路径:
/:拦截所有普通HTTP请求,不拦截.jsp页面,是标准配置;/*:拦截包含JSP在内的全部请求,会导致页面被控制器拦截,页面404,禁止使用。
5. Spring两级容器关系
Spring存在父子容器:
- 父容器(根容器):管理Service、Mapper、工具Bean;
- DispatcherServlet子容器:管理Controller、拦截器; 子容器可获取父容器所有Bean,父容器无法访问子容器Bean;SpringBoot自动整合两级容器,无需手动配置。
六、总结
SpringMVC依托Servlet实现,以DispatcherServlet为调度核心,通过分层组件拆分请求处理全流程,实现了请求分发、参数绑定、业务调用、视图渲染完整能力。 对比原生Servlet,它依托注解简化开发、分层解耦、支持REST接口;如今SpringBoot虽大幅简化配置,但Web开发底层依旧完全依赖SpringMVC整套执行逻辑。