SpringMVC 到底是怎么干活的?

知道大家写后端接口的时候,有没有好奇过,我们浏览器发一个请求,给到 SpringMVC 项目里面,它内部到底经过了哪些步骤,最后把结果又返回给浏览器。DispatcherServlet、HandlerMapping、HandlerAdapter、ViewResolver,这一堆名词看着头大却又不理解。今天我们用很通俗的方式讲一遍 SpringMVC 完整执行流程。其实SpringMVC工作原理根本没有想象的复杂!

完整的请求执行流程

1. 浏览器发起请求,请求抵达 DispatcherServlet

用户在浏览器输入地址,或者前端发 ajax 请求,http 请求过来,首先会被 DispatcherServlet 拦截接收。所有请求都汇集到这,它不直接处理业务,专门做调度分发,相当于公司的前台,收到外来访客,不会自己干活,负责往下派活。

(补充:DispatcherServlet,前端控制器,整个 SpringMVC 的大总管,所有请求第一个找的就是它。)

2.DispatcherServlet 调用 HandlerMapping(处理器映射器)

大总管拿到请求之后,得知道这个请求该交给哪个 Controller 里面哪个方法去处理。于是去找 HandlerMapping。HandlerMapping 里面存好地址和方法的对应关系,比如/user/list对应 UserController 里的 list () 方法。它根据请求的 URL 去找匹配的处理器,找到之后,返回一个 Handler 执行链(里面包含我们写的 Controller 方法,还有配套拦截器),交还给 DispatcherServlet。

(简单说:HandlerMapping 的工作 ------ 查地址,找到该调用哪个 Controller。)

3.DispatcherServlet 调用 HandlerAdapter(处理器适配器)

拿到 Controller 的信息之后,DispatcherServlet 不会直接调用 Controller 方法。为什么搞个适配器?因为处理器的类型可能不止 Controller 这一种,适配器做适配,统一调用规则。 HandlerAdapter 拿到 handler 信息,它负责真正执行我们 Controller 里面写的业务方法 。 这里还会做参数绑定:把前端传过来的请求参数,封装成我们 Controller 方法上的形参,注意@RequestParam、@RequestBody 这些注解就是在这里生效。参数校验也发生在这一步。

4. 执行 Controller 中的自定义业务代码

适配器调用 Controller 里面的业务方法,咱们写的查询、新增逻辑在这里跑。 Controller 执行完之后,不会直接返回页面 / 数据,返回一个ModelAndView对象。)

  1. 如果是传统页面开发:Model 存数据,View 存要跳转的页面名字;
  2. 如果现在前后端分离接口,加了 @ResponseBody,直接把数据写入响应,就不走页面解析那一步。

5.HandlerAdapter 将 ModelAndView 返回给 DispatcherServlet

业务方法跑完,结果包装成 ModelAndView 交回大总管 DispatcherServlet。

(小插曲:如果加了 @ResponseBody,在这一步就会通过消息转换器,把对象转成 JSON 字符串,直接写回响应,后面视图解析就跳过。现在做后端开发大部分都是这个(B/S前后端分离)模式。)

6.DispatcherServlet 调用 ViewResolver(视图解析器)

如果不是返回 JSON,是要跳转页面,就走到视图解析器 ViewResolver。 它拿到 View 名字,拼接前缀后缀,把逻辑视图名转成真实物理视图,比如"user/list"拼接成/WEB-INF/jsp/user/list.jsp。解析完成,返回真正的 View 对象。

7. 视图渲染,向浏览器返回最终响应

拿到真实 View 之后,做视图渲染,把 Model 里面存放的数据填充到 jsp 页面里面,生成最终的 html 内容。 最后 DispatcherServlet 把最终的响应结果返回浏览器,一次完整请求到此结束。

总结:

总的来说 SpringMVC 把一次 HTTP 请求拆分成多个组件分工协作,每个组件各司其职、解耦配合,弄懂这套流程,再写接口时就不再只停留在调用 API 的表层,能够看透框架背后到底在帮我们做哪些事。

相关推荐
鶴哥只手遮天1 小时前
Spring Framework 7.0.9 深度剖析-05-配置元数据解析:XML、注解与 JavaConfig
java·后端·开源
NGINX开源社区1 小时前
与我们交流:NGINX Gateway Fabric 与 NGINX Ingress Controller 社区会议
java·服务器·前端
鶴哥只手遮天1 小时前
Spring Framework 7.0.9 深度剖析-16-异步与调度
java·后端·开源
十年Java程序媛1 小时前
Java 多线程基础与锁机制|进程线程、synchronized、volatile、Lock 面试全梳理
java·spring boot·面试
弈栈录1 小时前
大模型服务抽象:兼容 OpenAI、通义千问与本地模型
java·后端·架构
鶴哥只手遮天1 小时前
Spring Framework 7.0.9 深度剖析-06-Bean 生命周期与依赖注入原理
java·后端·开源
电子制造自留地1 小时前
AI服务器高多层PCB设计:阻抗控制、层间对位与孔金属化工程要点
大数据·网络·人工智能·科技·pcb工艺
唐钰小宝B1 小时前
深度解读 JDK 8、JDK 11、JDK 17 和 JDK 21 的区别
java·开发语言·windows
golang学习记2 小时前
最新版VS Code开发Spring Boot项目保姆级教程
java·spring boot·vscode·后端