一次请求 SpringMVC 到底做了什么?


0x0 先看名词

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

0x1 一个请求过来

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

一次请求 SpringMVC 到底做了什么?


0x01 请求处理器

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

一次请求 SpringMVC 到底做了什么?

0x02 视图解析器

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

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

类:ContentNegotiatingViewResolver

一次请求 SpringMVC 到底做了什么?

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

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

一次请求 SpringMVC 到底做了什么?

一次请求 SpringMVC 到底做了什么?


得到 ModelView 以后,视图解析器的任务就算完成了


0x03 合并模板

下一步跳转到 视图处理

一次请求 SpringMVC 到底做了什么?

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

一次请求 SpringMVC 到底做了什么?

组装 ModelAndView

一次请求 SpringMVC 到底做了什么?

执行视图合并

一次请求 SpringMVC 到底做了什么?

一次请求 SpringMVC 到底做了什么?

获取模板文件和语言信息

一次请求 SpringMVC 到底做了什么?

将 ModelAndView 中的属性全部传递给 FreeMarker

一次请求 SpringMVC 到底做了什么?

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

一次请求 SpringMVC 到底做了什么?

0x2 静态资源处理

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

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

一次请求 SpringMVC 到底做了什么?


分享到:


相關文章: