首页 > 编程语言 > 详细

深入理解Spring系列之十:DispatcherServlet请求分发源码分析

时间:2018-05-30 23:25:53      阅读:312      评论:0      收藏:0      [点我收藏+]

转载 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请求分发源码分析

原文:https://www.cnblogs.com/zhangjianbin/p/9114017.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!