深入理解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 ...
随机推荐
- webgl 初识2
之前的文章介绍了webgl. 这里进一步精简. WebGL的全部内容就是创建不同的着色器, 向着色器提供数据然后调用gl.drawArrays 或 gl.drawElements 让WebGL调用当前 ...
- 主流的RPC框架有哪些
RPC是远程过程调用的简称,广泛应用在大规模分布式应用中,作用是有助于系统的垂直拆分,使系统更易拓展.Java中的RPC框架比较多,各有特色,广泛使用的有RMI.Hessian.Dubbo等.RPC还 ...
- Bare metal APIs with ASP.NET Core MVC(转)
ASP.NET Core MVC now provides a true "one asp.net" framework that can be used for building ...
- Deepin系统又损坏了!
1.首先,去Deepin官方下载镜像(记得MD5检验一下).2.提取ISO里的安装程序到桌面,执行之&写入.(提醒:勾选下面的支持BIOS启动的选项,自测深度的UEFI很不稳定,建议不使用UE ...
- JMeter脚本强化之检查点
上一篇讲述了对脚本做参数化的两种方法,并对参数化设置结果做了简单的验证,就是通过添加断言.本篇将详细一点介绍怎么使用断言做文本检查,或者叫做设置检查点. 首先来看看下面的三个图,这三个图是用查看结果树 ...
- bzoj4569-萌萌哒
题目 有一个长度为\(n\)的十进制数,用\(s\)表示.有\(m\)个限制条件,每个条件形如:\((l_1,r_1,l_2,r_2)\),表示\(s[l_1:r_1]=s[l_2:r_2]\). 现 ...
- 实现对一个8bit数据的指定位的置0或者置1操作,并保持其他位不变。
给定函数原型:void bit_set(unsigned char *p_data,unsigned char positin,int flag) 参数说明:p_data是指定的源数据:positio ...
- 【BZOJ4455】小星星(动态规划,容斥)
[BZOJ4455]小星星(动态规划,容斥) 题面 BZOJ 洛谷 Uoj 题解 题意说简单点就是给定一张\(n\)个点的图和一棵\(n\)个点的树,现在要让图和树之间的点一一对应,并且如果树上存在一 ...
- bzoj1907: 树的路径覆盖(树形DP)
一眼题... f[i][0]表示在i连接一个子树的最小值,f[i][1]表示在i连接两个子树的最小值,随便转移... 样例挺强的1A了美滋滋... UPD:学习了2314的写法之后短了好多T T #i ...
- 【loj6059】Sum
Portal --> loj6059 Solution 看过去第一反应是..大力数位dp!然后看了一眼数据范围... 但是这没有什么关系!注意到我们不需要考虑前导零了,可以直接快乐dp ...