欢迎光临散文网 会员登陆 & 注册

Spring MVC之调用

2022-05-16 10:29 作者:做架构师不做框架师  | 我要投稿


前言

在上篇文章我们讲解了SpringMVC是如何初始化的,在这篇文章中会讲到其工作流程。

工作流程

大致流程如下:

  1. 用户发起请求一个url到中央控制器

  2. 中央控制器接收到请求后调用处理器映射器以获取相应的处理器(即controller)

  3. 处理器映射器返回处理器的位置给中央控制器

  4. 中央控制器调用处理器适配器获取到指定的处理器(即controller)

  5. 处理器适配器把请求交给指定的处理器执行请求

  6. 处理器执行完业务逻辑后,返回数据和视图给处理器适配器

  7. 处理器适配器把数据和视图返回给中央处理器

  8. 中央处理器请求视图解析器进行视图解析

  9. 视图解析器解析相应的视图并返回给中央控制器

  10. 中央控制器通过view将数据和模型填充到视图中

  11. view渲染完视图后返回给中央控制器

  12. 中央控制器把结果响应给用户


注意:本文是以5.2.3版本为讲解。

步骤一:控制请求的转发

业务逻辑如下:

  • 保留请求属性的快照,以便能够恢复原始属性

  • 给请求体加入一些默认属性,例如:当前环境处理器、主题处理器等

  • doDispatch:具体处理请求的转发

  • 并发处理未开始或可能已完成并且请求进一步处理并发结果时,恢复原始快照

在这里doDispatch是我们要关注的核心方法.

步骤二:具体处理请求的转发

处理程序将通过按顺序应用servlet的handler映射来获得。HandlerAdapter将通过查询servlet安装的HandlerAdapter来获得,以找到第一个支持handler类的HandlerAdapter。所有HTTP方法都由该方法处理。由HandlerAdapter或处理程序自己决定哪些方法是可以接受的。业务逻辑如下:

  • checkMultipart:检查是否是文件上传的请求

  • getHandler:获取当前请求的 HandlerExecutionChain,该链上包含处理器及拦截器集合,如果不存在报404异常

  • getHandlerAdapter:获取当前请求的处理器适配器

  • 处理以last-modified请求头的请求

  • applyPreHandle:应用注册拦截器的 preHandle 方法

  • handle:实际上调用处理程序

  • applyDefaultViewName:处理结果视图对象

  • applyPostHandle:应用已注册拦截器的 postHandle 方法

  • processDispatchResult:处理处理器选择和处理程序调用的结果,可以是 ModelAndView,也可以是要解析为 ModelAndView 的 Exception

  • applyAfterConcurrentHandlingStarted:请求成功响应之后的方法

步骤三:获取当前请求的HandlerExecutionChain

循环遍历我们初始化<url,controller>哈希表中找到相匹配的执行链

步骤四:查找请求的处理程序

查找请求的处理程序,如果找不到特定的处理程序,则返回默认处理程序。在这里有两个核心方法:

  • getHandlerInternal:查找指定请求的处理程序

  • getHandlerExecutionChain:为指定的处理程序构建一个 HandlerExecutionChain,包括拦截器

步骤五:获取当前请求的处理器适配器

看到这里我们应该很熟悉了,在讲解aop的时候我们也用到了supports方法,经典的适配器模式。

步骤六:应用注册拦截器的preHandle方法

业务逻辑如下:

  • 通过getInterceptors方法获取所有的拦截器

  • 循环遍历拦截器触发处理器拦截器上的afterCompletion方法回调

步骤七:实际上调用处理程序

实际调用的是AbstractHandlerMethodAdapter#handle()方法,该方法具体实现是在RequestMappingHandlerAdapter类中实现。

步骤八:使用指定的处理程序方法来处理请求

步骤九:调用方法来处理请求并返回结果视图

这个方法很长,但我们只关心下面两个核心方法:

  • invokeAndHandler:反射调用方法处理请求

  • getModelAndView:返回结果视图

步骤十:反射调用方法处理请求

在这里我们重点关注下invokeForRequest方法,这个方法通过请求的上下文解析参数值然后反射调用该方法。

步骤十一:解析参数及反射调用方法

业务逻辑如下:

  • getMethodArgumentValues:获取当前请求的方法参数值,检查提供的参数值并回退到配置的参数解析器,结果数组将被传递到 doInvoke

  • doInvoke:使用给定的参数值调用处理程序方法

步骤十二:返回结果视图

步骤十三:处理结果视图对象

步骤十四:应用已注册拦截器的postHandle方法

业务逻辑如下:

  • 通过getInterceptors方法获取所有的拦截器

  • 循环遍历拦截器触发处理器拦截器上的postHandle方法

步骤十五:处理处理器选择和处理程序调用的结果

核心业务逻辑如下:

  • 如果异常非空,处理异常

  • 结果视图非空,渲染给定的ModelAndView

步骤十六:按名称解析视图

核心业务逻辑如下:

  • resolveViewName:解析视图名称

  • reender:获取视图

步骤十七:组装视图

时序图

写在最后

好兄弟可以点赞并关注我的公众号“javaAnswer”,全部都是干货。


Spring MVC之调用的评论 (共 条)

分享到微博请遵守国家法律