转载 https://mp.weixin.qq.com/s/-kEjAeQFBYIGb0zRpST4UQ

DispatcherServlet是SpringMVC的核心分发器,它实现了请求分发,是处理请求的入口,本篇将深入源码分析它的请求分发过程

Servlet在service方法中进行请求接收与分发,DispatcherServlet的service方法继承自HttpServlet,具体代码如下图所示。

在FrameworkServlet中对这个protected修饰的service方法进行了重写,重写的目的是支持PATCH方式请求,具体代码如下图所示。

上述分析中的doGet、doPost等方法在HttpServlet中没有实际可用的实现,如果要使用这些方法,子类需要重写这些方法,DispatcherServlet没有重写这些方法,在DispatcherServlet的父类FrameworkServlet中进行了重写,看几个重写后的方法代码。

可以看到这些请求都会进入当前FrameworkServlet类的processRequest方法进行处理,具体代码如下图所示。

FrameworkServlet中的doService是一个抽象方法,DispatcherServlet重写了这个方法,具体代码如下图。

进入doDispatch方法,这个方法实现了将请求分发到具体Handler、执行拦截器的preHandle方法、调用Handler(编写的Controller)处理具体逻辑、执行拦截器的postHandle方法、处理返回的ModelAndView或异常、执行拦截器的afterCompletion方法,具体代码如下

上图描述中的HandlerMethod和HandlerExecutionChain代码如下所示。

总结

首先,SpringMVC框架在启动的时候会遍历Spring容器中的所有bean,对标注了@Controller或@RequestMapping注解的类中方法进行遍历,将类和方法上的@RequestMapping注解值进行合并使用@RequestMapping注解的相关参数值(如value、method等)封装一个RequestMappingInfo将这个Controller实例、方法及方法参数信息(类型、注解等)封装到HandlerMethod中,然后以RequestMappingInfo为key,HandlerMethod为value存到一个以Map为结构的handlerMethods中。

接着,将@RequestMapping注解中的value(即请求路径)值取出,即url,然后以url为key,以RequestMappingInfo为value,存到一个以Map为结构的urlMap属性中。

客户端发起请求的时候,根据请求的URL到urlMap中查找,找到RequestMappingInfo,然后根据RequestMappingInfo到handlerMethods中查找,找到对应的HandlerMethod,接着将HandlerMethod封装到HandlerExecutionChain;接着遍历容器中所有HandlerAdapter实现类,找到支持这次请求的HandlerAdapter,如RequestMappingHandlerAdapter,然后执行SpringMVC拦截器的前置方法(preHandle方法),然后对请求参数解析及转换,然后(使用反射)调用具体Controller的对应方法返回一个ModelAndView对象,执行拦截器的后置方法(postHandle方法),然后对返回的结果进行处理,最后执行afterCompletion方法。

深入理解Spring系列之十:DispatcherServlet请求分发源码分析的更多相关文章

  1. 深入理解Spring系列之十二:@Transactional是如何工作的

    转载 https://mp.weixin.qq.com/s/ZwhkUQF1Nun9pNrFI-3a6w 首先从说起.配置了,就必定有对应的标签解析器类,查看NamespaceHandler接口的实现 ...

  2. 深入理解Spring系列之七:web应用自动装配Spring配置

    转载 https://mp.weixin.qq.com/s/Lf4akWFmcyn9ZVGUYNi0Lw 在<深入理解Spring系列之一:开篇>的示例代码中使用如下方式去加载Spring ...

  3. 深入理解Spring系列之六:bean初始化

    转载 https://mp.weixin.qq.com/s/SmtqoELzBEdZLo8wsSvUdQ <深入理解Spring系列之四:BeanDefinition装载前奏曲>中提到,对 ...

  4. 深入理解Spring系列之五:BeanDefinition装载

    转载 https://mp.weixin.qq.com/s/1_grvpJYe8mMIAnebMdz9Q 接上篇<深入理解Spring系列之四:BeanDefinition装载前奏曲>,进 ...

  5. 深入理解Spring系列之四:BeanDefinition装载前奏曲

    转载 https://mp.weixin.qq.com/s?__biz=MzI0NjUxNTY5Nw==&mid=2247483835&idx=1&sn=276911368d4 ...

  6. 深入理解Spring系列之三:BeanFactory解析

    转载 https://mp.weixin.qq.com/s?__biz=MzI0NjUxNTY5Nw==&mid=2247483824&idx=1&sn=9b7c2603093 ...

  7. 深入理解Spring系列之二:BeanDefinition解析

    转载 https://mp.weixin.qq.com/s?__biz=MzI0NjUxNTY5Nw==&mid=2247483814&idx=1&sn=ddf49931d55 ...

  8. Flask系列10-- Flask请求上下文源码分析

    总览 一.基础准备. 1. local类 对于一个类,实例化得到它的对象后,如果开启多个线程对它的属性进行操作,会发现数据时不安全的 import time from threading import ...

  9. 一步步实现windows版ijkplayer系列文章之三——Ijkplayer播放器源码分析之音视频输出——音频篇

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

随机推荐

  1. 条形码生成库 BarcodeLib

    官方介绍 在ASP.NET,Windows,Reporting Service,Crystal Reports 和 RDLC Reports应用程序中轻松生成条形码 生成准确的条形码图像,并可以保存为 ...

  2. javascript之彻底理解prototype

    prototype很简单, 就是提供一种引用的机制. let BaseObject = { toString(){ return this.str; }, }; let Object1 = {str: ...

  3. Django 2.0 学习(17):Django 用户认证(auth模块)

    Django 用户认证(auth模块) 一.认证登陆 在进行用户登陆验证的时候,如果是自己写代码,就必须要先查询数据库,看用户输入的用户名是否存在于数据库中:如果用户存在于数据库中,然后再验证用户输入 ...

  4. Ubuntu 18.04开发环境部署流程

    部署流程 安装系统 安装Eclipse和jre 配置系统 安装辅助工具 安装系统 用安装盘安装即可. 一般boot 1G,swap按内存大小,home 20G,根剩余. 安装Eclipse和jre 解 ...

  5. Shell脚本修改Nginx upstream配置文件

    #!/bin/bash ##################################################### # Name: change_nginx_upstream_conf ...

  6. atcoder 2017Code festival C ——D题 Yet Another Palindrome Partitioning(思维+dp)

    题目大意: 把一个字符串s分割成m个串,这m个串满足至多有一种字符出现次数为奇数次,其他均为偶数次,问m的最小值 题解: 首先我们想一下纯暴力怎么做 显然是可以n^2暴力的,然后dp[i]表示分割到i ...

  7. [洛谷P1642]规划

    题目大意:有一棵$n(n\leqslant100)$个点的树,每个点有两个权值$a,b$,要求选择一个$m$个点的连通块$S$,最大化$\dfrac{\sum\limits_{i\in S}a_i}{ ...

  8. 【SYZOJ279】滑稽♂树(树套树)

    [SYZOJ279]滑稽♂树(树套树) 题面 SYZOJ CJOJ 题目描述 zzsyz实验楼里面种了一棵滑稽树,只有滑稽之力达到大乘期的oier才能看到.虽然我们看不到,但是还是知道一些信息: 这真 ...

  9. 表格隔行变色_CSS实现鼠标悬停高亮

    <!doctype html> <html> <head> <meta http-equiv="content-type" content ...

  10. Canny边缘检测算法原理及其VC实现详解(一)

    转自:http://blog.csdn.net/likezhaobin/article/details/6892176 图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个 ...