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请求的处理:
通过代码分析,对于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中请求流程入口已分析完毕。