专业的编程技术博客社区

网站首页 > 博客文章 正文

Spring MVC之调用(springmvc调用controller)

baijin 2024-08-20 10:14:14 博客文章 6 ℃ 0 评论

前言

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

工作流程

大致流程如下:

  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”,全部都是干货。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表