SpringMVC工作流程源码剖析

原文链接:

https://juejin.im/post/5e6b0ee3e51d4526f65cdb50.

0x0 先看名词

  • DispactherServlet:SpringMVC 的心脏,所有的请求从这里进入,也从这里出去
  • HandlerAdapter:请求处理器
  • HandlerMapping:请求和处理对象间的映射关系,可以理解为 地址 /api 对应 @RequestMapping("/api")
  • doDispatchSpringMVC 处理请求的方法
  • ModelAndView:视图响应对象,例如我们Controller返回一个字符串,都会被包装成它
  • ViewResolvers:视图解析器,解析响应结果为浏览器能识别的网页或者文件
  • ContentNegotiatingViewResolverSpringMVC 提供的视图内容协商器,根据响应视图类型来判断使用哪个解析器来解析,是使 SpringMVC 支持多视图解析器的重要组件,官方说明:https://spring.io/blog/2013/06/03/content-negotiation-using-views

0x1 一个请求过来

请求进入 DispactherServlet 会被分配给 doDispatch ,所以直接断点 doDispatch 即可

SpringMVC工作流程源码剖析_第1张图片

0x01 请求处理器

doDispatch 会匹配相应的 HandlerMapping (可以理解为你在 Controller 中写的方法),然后执行并拿到返回结果(也就是 ModelAndView)

SpringMVC工作流程源码剖析_第2张图片

0x02 视图解析器

DispactherServlet 会将ModelAndView交给 ViewResolvers(也就是常说的视图解析器) 解析处理。

ViewResolversContentNegotiatingViewResolver(详见 0x0 解释)它去问所有的视图解析器:这个 ModelAndView 你们能解析的了吗?,如下图:

类:ContentNegotiatingViewResolver
SpringMVC工作流程源码剖析_第3张图片

如何确定谁才是天选之子解析器?MediaType!按照顺序,第一个符合 MediaType 的解析器将被使用。

PS:比如你响应的是 text/html 文件,但是 text/html 解析器有两个,你想优先使用其中一个的话,你就得为该解析器设置 Order (详见 0x0 中官方说明)

SpringMVC工作流程源码剖析_第4张图片

SpringMVC工作流程源码剖析_第5张图片
得到 ModelView 以后,视图解析器的任务就算完成了

0x03 合并模板

下一步跳转到 视图处理

SpringMVC工作流程源码剖析_第6张图片

进入 render 方法后,会执行 Prepares the view given the specified model, merging it with static ,通俗讲就是将我们 Request 域或者 Session域 中的值(比如说请求参数回显)和视图解析出来的 ModelAndView 进行合并,这也是为什么我们再模板中可以轻松获得各种作用域值的原因,继续往下看

SpringMVC工作流程源码剖析_第7张图片

组装 ModelAndView

SpringMVC工作流程源码剖析_第8张图片

执行视图合并

SpringMVC工作流程源码剖析_第9张图片

SpringMVC工作流程源码剖析_第10张图片

获取模板文件和语言信息

SpringMVC工作流程源码剖析_第11张图片

ModelAndView 中的属性全部传递给 FreeMarker

SpringMVC工作流程源码剖析_第12张图片

最后一步生成 Html 并响应到浏览器

SpringMVC工作流程源码剖析_第13张图片

0x2 静态资源处理

SpringMVC 在视图处理器如果找不到合适的处理器的情况下,就会视该请求为静态资源请求并使用静态资源解析器解析该请求。

默认的静态资源目录如下,这也是为什么你将静态资源放在 resource 目录的时候不需要任何配置便可访问的原因

SpringMVC工作流程源码剖析_第14张图片

如果本文对你有帮助,欢迎关注并点赞~ 任何问题请评论区或者公众号留言。

关注本人公众号,收获双倍快乐

SpringMVC工作流程源码剖析_第15张图片

技术交流群,广告勿+

SpringMVC工作流程源码剖析_第16张图片

你可能感兴趣的:(SpringBoot)