文章目录

  • 步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理
  • 继承关系
  • 入口 DispatcherServlet#doDispatch
  • 多文件上传解析
  • 获取处理器
  • handler的完整注册流程
  • 获取HandlerAdapter
  • 执行拦截器PreHandle
  • 执行HandlerAdapter.handle
  • 参数解析器HandlerMethodArgumentResolver
  • @RequestBody的实现逻辑
  • handler方法返回值处理器
  • @ResponseBody的实现逻辑
  • 执行拦截器postHandle
  • 执行拦截器的afterCompletion
  • 异常的处理
  • Spring MVC 学习笔记深入源码


步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理

继承关系

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器

DispatcherServlet继承自最基础的HttpServlet

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_02

DispatcherServlet父类FrameworkServlet中实现了dotGet、doPost等do方法,都是调用了processRequest(request, response);

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_03

这方法里又调doService(request, response);

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_04

又调了doDispatch(request, response); 开始转发请求

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_05

入口 DispatcherServlet#doDispatch

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_06

多文件上传解析

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_原理_07

processedRequest = checkMultipart(request);

代码就不贴了,很简单,自己可以点进去看,就检查method 为post,content type 是否以multipart/ 开头的,如果是则执行解析多文件上传请求,把文件封装为MultipartFile对象,设置在请求内部属性里MultiValueMap<String, MultipartFile> multipartFiles

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_08

获取处理器

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_09

mappedHandler = getHandler(processedRequest);

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_10

平时我们写的@RequestMapping(“/xxx”)就是这个接口的一个实现:RequestMappingHandlerMapping

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_11

打开这个类看可以看到Creates RequestMappingInfo instances from type and method-level @RequestMapping annotations in @Controller classes

注释写到 通过在@Controller类的方法中使用@RequestMapping来注册RequestMappingInfo实例

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_12

handler的完整注册流程

我们看下这个是怎么注册的,搜索RequestMappingHandlerMapping的使用,找到这个地方注入的,WebMvcAutoConfiguration,这个类在

spring-boot-autoconfigure-2.2.3.RELEASE.jar这个包里

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_13

先创建了RequestMappingHandlerMapping对象,再塞入拦截器等组件

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_原理_14

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_15

而RequestMappingHandlerMapping继承了AbstractHandlerMethodMapping,AbstractHandlerMethodMapping这个实现了InitializingBean接口

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_16

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_17

在afterPropertiesSet方法里调用了初始化方法initHandlerMethods()

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_18

拿到上下文容器里的所有bean,逐个处理,执行processCandidateBean

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_19

判断这个bean是不是handler,如果是就执行detectHandlerMethods,去检测handler方法

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_原理_20

对类中的方法逐个执行getMappingForMethod,去拿RequestMappingInfo,这个方法不是的话就返回的null

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_21

看下面两个代码图,你可以知道,是去检测了注解@RequestMapping,如果有就封装为RequestMappingInfo返回,没有就返回null。

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_22

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_23

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_24

最后全部扫描完,注册上去

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_25

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_26

可以看到最后其实就是放到了MappingRegistry类的属性map里存着了

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_27

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_28

获取HandlerAdapter

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_29

实际上内部就是逐个HandlerAdapter调了下supports方法看是不是支持,谁支持就返回谁

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_30

我们看到,这个handler适配器总共就只有几种的

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_31

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_32

我们这种HandlerMethod适用于这个适配器

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_33

执行拦截器PreHandle

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_34

循环执行这个methodHandler要使用的拦截器interceptor的preHandle

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_原理_35

执行HandlerAdapter.handle

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_36

handle又直接调了handleInternal

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_37

执行invokeHandlerMethod

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_38

invokeHandlerMethod方法里把要的一些组件封装为一个ServletInvocableHandlerMethod,然后执行invocableMethod.invokeAndHandle(webRequest, mavContainer);

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_39

调用invokeForRequest执行请求

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_40

获取参数

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_41

参数解析器HandlerMethodArgumentResolver

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_42

@RequestBody的实现逻辑

参数解析器的接口,判断是否支持这个参数,以及解析参数的方法,有个常用的参数解析器,@RequestBody,我们探究下它的实现

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_43

查看实现类,搜body,就只剩这个了,进去看就是它

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_44

判断是否有注解@RequestBody

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_原理_45

我们看这个readWithMessageConverters

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_46

又调用了readWithMessageConverters来使用MessageConverter解析消息,底层使用了MappingJackson2HttpMessageConverter来解析,这也是为啥直接写个对象,然后用@RequestBody注解就能解析好请求的Body参数。后面还会讲解@ResponseBody实现原理。

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_原理_47

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_原理_48

执行目标方法

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_49

handler方法返回值处理器

有个比较常见的返回值处理器就是RequestResponseBodyMethodProcessor

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_50

这个是HandlerMethodReturnValueHandler接口,用来对handler方法返回值做处理

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_51

@ResponseBody的实现逻辑

常用的@ResponseBody就是在这实现的

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_52

我们看下它的处理方法

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_53

继续进writeWithMessageConverters方法

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_54

我们看看HttpMessageConverter

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_55

就几个很简单的方法,能不能读,能不能写,读,写方法。看看实现类

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_56

我们看其中一个

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_springmvc_57

继承了AbstractJackson2HttpMessageConverter,那四个接口方法都是在AbstractJackson2HttpMessageConverter实现的,我们去看看

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_58

内部使用的ObjectMapper来实现的读写

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_59

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_60

执行拦截器postHandle

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_61

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_spring_62

执行拦截器的afterCompletion

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_拦截器_63

执行异常拦截器、拦截器interceptors的afterCompletion

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_64

至此,HandlerInterceptor的preHandle、postHandle、afterCompletion全部执行完了

步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理_服务器_65

异常的处理

查看我的另一个异常专篇 springmvc 全局异常处理器配置的三种方式&深入底层源码分析原理

Spring MVC 学习笔记深入源码

Spring MVC 学习笔记深入源码