• SpringMvc源码分析-请求流程(一)


    SpringMvc源码分析-从前端到接口请求流程

    SpringMvc执行流程

    其实SpringMVC请求原理很简单:说白了就是用一个DispatcherServlet 封装了一个Servlet的调度中心, 由调度中心帮我们调用我们的处理方法:在这个过程中调度中心委托给各个组件执行具体工作 ,比如帮我们映射方法请求、帮我解析参数、调用处理方法、响应数据和页面 等

    在这里插入图片描述

    名词解释

    DispatcherServlet

    它负责协调和组织不同组件完成请求处理并返回响应工作。它是SpringMVC统一的入口,所有的请求都通过它。

    ViewReslover

    根据ModelAndView的视图去找具体的jsp封装在View对象。

    View

    View是Spring MVC框架中的一个接口,它定义了如何渲染模型数据并生成响应。View对象负责将模型数据渲染为客户端可以理解的格式,例如HTML、JSON或XML等。

    Handler

    Handler表示请求处理器,(自己写的业务逻辑方法)。是一个Object类型的。在SpringMVC中有四种Handler:

    1.实现了Controller接口的Bean对象:这是Spring MVC最初的设计,每个请求对应一个Controller对象,每个Controller只处理一个单一的动作或者请求。该方式的优点是分工明确,缺点是如果请求很多,会产生大量的Controller类,增加了代码的复杂度。在Controller的handleRequest方法中,你可以直接操作HttpServletRequest和HttpServletResponse对象来处理请求和生成响应。

    //实现了Controller接口的Bean对象
    @Component("/login")
    public class HandlerDemo implements Controller {
    
       @Override
       public ModelAndView handleRequest
             (HttpServletRequest httpServletRequest,
              HttpServletResponse httpServletResponse)
             throws Exception {
          return new ModelAndView();
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.实现了HttpRequestHandler接口的Bean对象:这是另一种处理请求的方式。相比于Controller接口,HttpRequestHandler接口提供了更多的灵活性,因为你可以直接操作ServletRequest和ServletResponse。但是,它通常只用于处理一些特定的请求,比如文件上传和下载,而不是用于处理一般的用户请求。

    @Component("/login")
    public class HandlerDemo implements HttpRequestHandler {
       @Override
       public void handleRequest
             (HttpServletRequest request,
              HttpServletResponse response)
             throws ServletException, IOException {
          System.out.println(1);
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.添加了@RequestMapping注解的方法:只需要在任意一个Bean的方法上添加@RequestMapping注解,Spring MVC就会自动将这个方法映射到一个URL,然后当这个URL被请求时,Spring MVC会调用这个方法来处理请求。

    @RequestMapping("/showIndex2")
    public String index2(ModelAndView modelAndView) {
       modelAndView.addObject("user","zhangsan");
       return "a";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    HandlerMapping

    HandlerMapping是个接口,有不同的实现,HandlerMapping负责去寻找Handler,并且保存路径和Handler之间的映射关系。因为有不同类型的Handler,所以在SpringMVC中会由不同的HandlerMapping来负责寻找Handler,比如:

    • BeanNameUrlHandlerMapping:会把所有路径名(Bean的名称)以 “/” 开头的Bean都当作是一个Handler,BeanNameUrlHandlerMapping就会将这个Bean名称和对应的Bean实例保存到内部的一个Map结构中。然后存入到它的内部Map结构中。当接收到一个请求后,它会根据请求的URL路径去这个Map中查找对应的Handler。一般处理Controller接口和HttpRequestHandler接口
    • RequestMappingHandlerMapping:会把先把所有类上加有@Controller和@RequestMapping的bean找出来然后并解析@RequestMapping中的内容,比如method、path,封装为一个RequestMappingInfo对象,最后把RequestMappingInfo对象做为key,Method对象封装为HandlerMethod对象后作为value,存入Map。

    在寻找handler的时候spring会遍历所有的HandlerMapping,挨个寻找,找到了直接返回。

    HandlerAdaper

    负责调用handler的具体方法,并返回试图的名称。由于我们有好几种handler,分别存放在不同的HandlerMapping中,有的handler是方法,有的是实例。

    • 实现了Controller接口的Bean对象,执行的是Bean对象中的handleRequest()
    • 实现了HttpRequestHandler接口的Bean对象,执行的是Bean对象中的handleRequest()
    • 添加了@RequestMapping注解的方法,具体为一个HandlerMethod,执行的就是当前加了注解的方法

    spring在拿到handler后,它会遍历所有已注册的HandlerAdapter,调用它们的supports()方法来检查是否支持当前handler类型。如果支持,则使用该HandlerAdapter来处理请求。

    可以理解为:

    for(HandlerAdapter adapter : this.handlerAdapters)){
        if(adapter.supports(handler)){
            //具体执行方法逻辑,去解析Request对象,传参,执行逻辑
            adapter.handle(request,response,handler);
        }
    }
    //各个adapters中的supports可以理解为
    public boolean supports(Object handler) {
        return (handler instanceof Controller);
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    请求的流程:

    1. 用户发送请求到DispatcherServlet。
    2. dispatcherServlet收到请求调用处理器映射器HandlerMapping,当HandlerMapping找到一个匹配的处理程序时,它会创建一个HandlerExecutionChain对象,HandlerExecutionChain是一个包含处理程序和所有匹配的拦截器(HandlerInterceptor)的对象。拦截器可以在请求处理之前和之后执行额外的操作,最后将HandlerExecutionChain返回给dispatcherServlet。
    3. DispatcherServlet会根据处理器Handler找到处理器适配器HandlerAdaper。执行参数封装,数据格式转换,数据验证等操作
    4. HandlerAdaper执行处理器处理器Handler,并将结果ModelAndView返回给DispatcherServlet。
    5. dispatcherServlet将ModelAndView传给视图解析器ViewReslover。
    6. ViewReslover将解析ModelAndView并返回view给disatcherServlet。
    7. dispatcherServlet对view进行渲染试图。

    dispatcherServlet解释请求流程

    其实上述的流程都是在DispatcherServlet的doDispatch里完成的。

    img

    DispatcherServlet 是一个继承自 Servlet 的关键组件,因此当接收到请求时,会首先进入 Servletservice 方法,然后调用 doGet/doPost 方法,最后进入 processRequestdoService 方法,从而触发 doDispatch 方法。这个 doDispatch 方法中,执行了以下关键步骤:

    1、检查请求类型:首先,会检查是否是文件上传的请求。如果是,则进行相应的处理。

    processedRequest = checkMultipart(request);
    
    • 1

    2、获取handler:然后根据请求获取 HandlerExecutionChain。如果没有找到对应的处理器链,那么就会返回404错误。

    HandlerExecutionChain mappedHandler = getHandler(processedRequest);
    if(mappedHandler == null){
        noHandlerFound(processedRequest, response);
        return; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    3、查找适配器:有了handler,就可以通过处理器找到对应的适配器 HandlerAdapter。这个适配器是 Spring MVC 中的一个关键组件,它使得 Spring MVC 可以支持多种类型的处理器,不仅仅是一个。

    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
    • 1

    4、执行前置拦截器:这个步骤会执行所有的前置拦截器。

    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
        return;
    }
    
    • 1
    • 2
    • 3

    5、处理请求:然后 HandlerAdapter 会执行处理器中的一系列操作,如参数封装,数据格式转换,数据验证等。

    ModelAndView mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    
    • 1

    6、设置默认视图:如果 ModelAndView 中没有设置视图,那么这里会为其设置一个默认视图。

    applyDefaultViewName(processedRequest, mv);
    
    • 1

    7、执行后置处理器:在处理完请求后,这个步骤会执行所有的后置处理器。

    mappedHandler.applyPostHandle(processedRequest, response, mv);
    
    • 1

    8、渲染视图并响应用户:最后,DispatcherServlet 会将 ModelAndView 对象传给 ViewReslover 视图解析器进行解析,得到具体的视图对象,并进行视图渲染,最后响应给用户。

    processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    
    • 1

    接下来的内容,我们将更深入地探索 Spring MVC 的工作机制,比如Tomcat启动后Spring MVC是如何创建的,handlerMapping 是如何找到对应的处理器的,adapter 是如何处理处理器的,以及 SPI 如何实现 Spring MVC 的。
    ler, mv, dispatchException);

    
    接下来的内容,我们将更深入地探索 Spring MVC 的工作机制,比如Tomcat启动后Spring MVC是如何创建的,`handlerMapping` 是如何找到对应的处理器的,`adapter` 是如何处理处理器的,以及 SPI 如何实现 Spring MVC 的。
    
    • 1
    • 2
  • 相关阅读:
    基于VUE + Echarts 实现可视化数据大屏煤改电分析系统
    Linux相关用法(时刻更新)
    电子标签模块:让传感器智能化,工程安全监测更便捷
    vue3 | defineExpose的使用
    面试美团被问到了Redis,搞懂这几个问题,让你轻松吊打面试官
    LeetCode每日一题——1732. 找到最高海拔
    配置mac与windows之间的ssh互连
    U盘装系统教程,一键安装和U盘安装的区别
    搭建知识库系统不难,选对工具很重要!
    WebSocket在线通信
  • 原文地址:https://blog.csdn.net/shouji6175/article/details/133805708