SpringMVC源码(四):MVC请求流程入口

1、请求流程入口逻辑分析

  在源码(二):MVC容器启动中,SpringMVC遵循Servlet的生命周期,Servlet生命周期主要有三个重要的方法init()、service()、destory()。其中service()是处理客户端请求的方法,查看DispatcherServlet及其父类是否有实现service()方法。在父类FrameworkServlet中找到service()方法。

  

  在实际开发中,常用的请求方式为GET、POSTE等,继续调试进入super.service()步骤,进入tomcat的代码RequestFacade#getHttpServletMapping(),Tomcat源码不是本次的重点,此处先忽略请求到Tomcat中的处理。

  

       

  详细分析FrameworkServlet中对GET、POST等请求的处理,发现不管何种请求都会调用同一个处理方法。

GET请求的处理:

  

POST请求的处理:

       0

通过代码分析,对于GET、POST、PUT、DELETE等请求方式,最终都会调用processRequest(request, response)方法。下面我们来看看processRequest()方法中是否有对请求调用的处理。

    

在Spring中,以do开头的方法就是实际处理流程的方法。在FrameworkServlet#processRequest中,DispatcherServlet#doService方法是真正处理请求的方法。

    

在DispatcherServlet#doService方法中执行请求的分发处理,调用DispatcherServlet#doDispatch方法。

2、请求流程入口流程图

   

3、请求流程入口源码分析

  FrameworkServlet#service 核心代码:

 1 // 重写父类方法为了拦截PATCH请求
 2 @Override
 3 protected void service(HttpServletRequest request, HttpServletResponse response)
 4       throws ServletException, IOException {
 5 
 6    // 获得请求方法
 7    HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
 8    // 处理patch请求
 9    if (httpMethod == HttpMethod.PATCH || httpMethod == null) {
10       processRequest(request, response);
11    }
12    else {
13       // 处理其他请求,如Get、Post、Delete等
14       super.service(request, response);
15    }
16 }

  DispatcherServlet#doService 核心伪代码:

 1 //  设置DispatcherServlet的请求属性,调用doDispatch方法实现请求的调度
 2 @Override
 3 protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
 4    // ...
 5    // 设置Spring框架中的常用对象到request属性中,属性会在handler和view中使用
 6    request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
 7    request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
 8    request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
 9    request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());
10 
11    // FlashMap的相关配置,主要用于Redirect转发时参数的传递
12    if (this.flashMapManager != null) {
13       FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);
14       if (inputFlashMap != null) {
15          request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));
16       }
17       request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());
18       request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);
19    }
20    
21    // 执行请求的分发
22    doDispatch(request, response);
23    
24    // ...
25 }

  至此,SpringMVC中请求流程入口已分析完毕。

 

posted @ 2023-02-13 19:57  无虑的小猪  阅读(293)  评论(0编辑  收藏  举报