深入理解Spring系列之十:DispatcherServlet请求分发源码分析
转载 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请求分发源码分析的更多相关文章
- 深入理解Spring系列之十二:@Transactional是如何工作的
转载 https://mp.weixin.qq.com/s/ZwhkUQF1Nun9pNrFI-3a6w 首先从说起.配置了,就必定有对应的标签解析器类,查看NamespaceHandler接口的实现 ...
- 深入理解Spring系列之七:web应用自动装配Spring配置
转载 https://mp.weixin.qq.com/s/Lf4akWFmcyn9ZVGUYNi0Lw 在<深入理解Spring系列之一:开篇>的示例代码中使用如下方式去加载Spring ...
- 深入理解Spring系列之六:bean初始化
转载 https://mp.weixin.qq.com/s/SmtqoELzBEdZLo8wsSvUdQ <深入理解Spring系列之四:BeanDefinition装载前奏曲>中提到,对 ...
- 深入理解Spring系列之五:BeanDefinition装载
转载 https://mp.weixin.qq.com/s/1_grvpJYe8mMIAnebMdz9Q 接上篇<深入理解Spring系列之四:BeanDefinition装载前奏曲>,进 ...
- 深入理解Spring系列之四:BeanDefinition装载前奏曲
转载 https://mp.weixin.qq.com/s?__biz=MzI0NjUxNTY5Nw==&mid=2247483835&idx=1&sn=276911368d4 ...
- 深入理解Spring系列之三:BeanFactory解析
转载 https://mp.weixin.qq.com/s?__biz=MzI0NjUxNTY5Nw==&mid=2247483824&idx=1&sn=9b7c2603093 ...
- 深入理解Spring系列之二:BeanDefinition解析
转载 https://mp.weixin.qq.com/s?__biz=MzI0NjUxNTY5Nw==&mid=2247483814&idx=1&sn=ddf49931d55 ...
- Flask系列10-- Flask请求上下文源码分析
总览 一.基础准备. 1. local类 对于一个类,实例化得到它的对象后,如果开启多个线程对它的属性进行操作,会发现数据时不安全的 import time from threading import ...
- 一步步实现windows版ijkplayer系列文章之三——Ijkplayer播放器源码分析之音视频输出——音频篇
一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...
随机推荐
- javascript 排序
// 插入排序 将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列. 从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置.(如果待插入的元素与有序 ...
- 【.Net】HttpClient 的使用
class Program { public static HttpClient Client; static HttpResponseMessage response; static void Ma ...
- el表达式作用域查找顺序 注意:当属性名字相同时候 先找到是小的作用域 因为是从小到大开始找的
- windows200364位iis6 php环境搭建
最近接一个小活,就是帮着部署个php网站,服务器是window2003,iis6.之前在我自己得服务器上已经搭建过php环境,区别是我的服务器windows2012,而对方的是windows 2003 ...
- pycharm中新建并且运行django
1.对于Bottle框架其本身未实现类似于Tornado自己基于socket实现Web服务,所以必须依赖WSGI,默认Bottle已经实现并且支持的WSGI有: 帮助我们写socket的server. ...
- Hyperledger Fabric 实战(十二): Fabric 源码本地调试
借助开发网络调试 fabric 源码本地调试 准备工作 IDE Goland Go 1.9.7 fabric-samples 模块 chaincode-docker-devmode fabric 源码 ...
- BZOJ3530:[SDOI2014]数数——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3530 我们称一个正整数N是幸运数,当且仅当它的十进制表示中不包含数字串集合S中任意一个元素作为其子 ...
- HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)
HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...
- Linux之Libcurl库的介绍与应用20170509
一.LibCurl简介 LibCurl是免费的客户端URL传输库,支持FTP,FTPS, HTTP, HTTPS, SCP, SFTP, TFTP, TELNET, DICT, FILE ,LDAP等 ...
- Linux之静态库与动态库20160706
所谓静态链接是指把要调用的函数或者过程链接到可执行文件中,成为可执行文件的一部分.当多个程序都调用相同函数时,内存中就会存在这个函数的多个拷贝,这样就浪费了宝贵的内存资源..so文件是共享库文件(动态 ...