关于springboot:Spring-MVC执行流程及源码详解

34次阅读

共计 3358 个字符,预计需要花费 9 分钟才能阅读完成。

Spring MVC 中各组件初始化过程已在上篇分享: 初始化过程


一、SpringMVC 罕用组件

  • DispatcherServlet:前端控制器,对立解决申请和响应,整个流程管制的核心,由它调用其它组件解决用户的申请
  • HandlerMapping:处理器映射器,依据申请的 url、method 等信息查找 Handler,即控制器办法
  • Handler:处理器,在 DispatcherServlet 的管制下 Handler 对具体的用户申请进行解决
  • HandlerAdapter:处理器适配器,通过 HandlerAdapter 对处理器(控制器办法)进行执行
  • ViewResolver:视图解析器,不须要工程师开发,由框架提供, 进行视图解析
  • View:视图 将模型数据通过页面展现给用户

二、DispatcherServlet(前端控制器)的继承构造

IDEA 中快捷键Ctrl+Shift+Alt+U 可查看继承图

graph TD
A[Servlet]
A==>B[GenericServlet]
B==>C[HttpServlet]
C==>D[HttpServletBean]
D==>E[FrameworkServlet]
E==>F[DispatcherServlet]

从上图中能够看到 DispatcherServlet 的顶层接口是Servlet

三、调用组件解决申请过程

$\color{#F00}{尽管咱们看的是不同类中的调用过程, 如果通过继承或者实现放到同一个类中}$
$\color{#F00}{其实咱们就是在同一个类中来查看办法的调用。}$

1.Servlet 接口

从 Servlet 接口开始步步剖析, 在 Servlet 接口中存在下图中的 5 种形象办法。
快捷键: Alt+7

用户每次发送申请时,Servlet 容器都会调用 service() 办法对申请进行解决

public interface Servlet {public void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;   
}

2.GenericServlet 抽象类

public abstract class GenericServlet implements Servlet, ServletConfig,
        java.io.Serializable {// 能够看到并没有对 Servlet 中的 service()办法进行实现
    @Override
    public abstract void service(ServletRequest req, ServletResponse res)
            throws ServletException, IOException;

}

GenericServlet 没有对 Servlet 中的 service()办法进行实现, 那么依据继承构造持续向下梳理

3.HttpServle 抽象类

能够看到又调用了 service(request, response) 办法, 如下图

申请形式有以下几种

依据 req.getMethod() 获取申请形式调用对应的 doGet,doPut 等等 办法, 持续向下看

4.HttpServletBean 抽象类

能够发现 HttpServletBean 没有重写 service() 办法, 用的是父类 HttpServle 中的办法

5.FrameworkServlet 抽象类

FrameworkServlet 中重写了 doGet 等办法, 则应用本类中重写后的办法

能够看到无论 service 中的那个逻辑, 都执行 processRequest(request, response) 办法, 所以咱们只需查看该办法即可

6.DispatcherServlet 类

6.1 执行流程图

为什么说 doDispatcher()是整个流程管制的核心, 由它调用其它组件解决用户的申请? 那么看下文流程即可明确
用户向服务器发送申请,申请被 SpringMVC 前端控制器 DispatcherServlet 捕捉。

执行流程图 大家能够对照图来看接下来的流程

6.2 图中第的 2,3 步处理器映射器

就是这一步返回处理器执行链蕴含拦截器

以后类重写了父类中的 doservice() 办法, 又发现该办法的外围是 doDispatcher 办法,重点来了 咱们来看该办法实现

6.3 图中第的 4,5,6,7 步处理器适配器

1. 蕴含拦截器的执行逻辑

接下来就到拦截器的前置办法, 首先看下拦截器的执行程序, 不便了解接下来的代码流程

请观赏源码流程:紧接上图中的适配器办法

拦截器的 前置办法 对应上图的逻辑解决(对上图详解)

正序 下来是理论调用处理程序办法 返回ModelAndView 对象

拦截器的 后置办法

6.4 图中第的 8,9,10

> 进入该办法查看
看拦截器的最初执行办法

返回用户

五、总结

1. 简略总结

1. Spring MVC 所有的申请都通过 DispatcherServlet 来对立散发。DispatcherServlet 将申请分发给 Controller 之前,须要借助于 Spring MVC 提供的 HandlerMapping 定位到具体的 Controller。
2. HandlerMapping 接口负责实现客户申请到 Controller 映射。
3. Controller 接口将解决用户申请,这和 Java Servlet 表演的角色是统一的。一旦 Controller 解决完用户申请,则返回 ModelAndView(数据和视图)对象给 DispatcherServlet 前端控制器。从宏观角度思考,DispatcherServlet 是整个 Web 利用的控制器;从宏观思考,Controller 是单个 Http 申请处理过程中的控制器,而 ModelAndView 是 Http 申请过程中返回的模型(Model)和视图(View)。
4. 返回的视图须要通过 ViewResolver 接口(视图解析器)在 Web 利用中负责查找 View 对象,从从而将相应后果渲染给客户。

2. 具体总结

1. 用户向服务器发送申请,申请被 SpringMVC 前端控制器 DispatcherServlet 捕捉
2. DispatcherServlet 对申请 URL 进行解析,失去申请资源标识符(URI),判断申请 URI 对应的映射
3. 依据该 URI,调用 HandlerMapping 取得该 Handler 配置的所有相干的对象(包含 Handler 对象以及 Handler 对象对应的拦截器),最初以 HandlerExecutionChain 执行链对象的模式返回。
4. DispatcherServlet 依据取得的 Handler,抉择一个适合的 HandlerAdapter。
5. 如果胜利取得 HandlerAdapter,此时将开始执行拦截器的 preHandler(…) 办法【正向】
6. 提取 Request 中的模型数据,填充 Handler 入参,开始执行 Handler(Controller)办法,解决申请。在填充 Handler 的入参过程中,依据你的配置,Spring 将帮你做一些额定的工作:

6.1. HttpMessageConveter:将申请音讯(如 Json、xml 等数据)转换成一个对象,将对象转换为指定的响应信息
6.2 HttpMessageConveter:将申请音讯(如 Json、xml 等数据)转换成一个对象,将对象转换为指定的响应信息
6.3 数据转换:对申请音讯进行数据转换。如 String 转换成 Integer、Double 等
6.4 数据格式化:对申请音讯进行数据格式化。如将字符串转换成格式化数字或格式化日期等
6.5 数据验证:验证数据的有效性(长度、格局等),验证后果存储到 BindingResult 或 Error 中

7. Handler 执行实现后,向 DispatcherServlet 返回一个 ModelAndView 对象。
8. 此时将开始执行拦截器的 postHandle(…)办法【逆向】。
9. 依据返回的 ModelAndView(此时会判断是否存在异样:如果存在异样,则执行 HandlerExceptionResolver 进行异样解决)抉择一个适宜的 ViewResolver 进行视图解析,依据 Model 和 View,来渲染视图。
10. 渲染视图结束执行拦截器的 afterCompletion(…)办法【逆向】。
11. 将渲染后果返回给客户端。

正文完
 0