SpringMvc源码解读笔记

2022年6月16日 369点热度 0人点赞 0条评论

工作机制中分三部来分析springmvc的源代码

  1. ApplicationContext初始化时建立所有url和controller类的对应关系(用Map保存)
  2. 根据请求url找到对应的controller,并从controller中找到处理请求的方法
  3. request参数绑定到方法的形参,执行方法处理请求,并返回结果视图

ApplicationContext初始化时建立所有url和controller类的对应关系(用Map保存)

Sptingboot中的调用链

RequestMappingHandlerMapping的注入依靠的是springboot的自动装配

1、自动装配:在spring-boot-autoconfigure包的spring.factories里面的WebMvcAutoConfiguration
2、WebMvcAutoConfiguration的内部类EnableWebMvcConfiguration#requestMappingHandlerMapping()
3、WebMvcConfigurationSupport#requestMappingHandlerMapping()

Spring中的调用链

1、springmvc开启注解声明,需要在xml中加入<mvc:annotation-driven/>标签

2、spring容器启动,扫描xml,加载BeanDefinition过程中,扫描到annotation-driven标签,使用AnnotationDrivenBeanDefinitionParser解析

3、AnnotationDrivenBeanDefinitionParser的parse方法将RequestMappingHandlerMapping注册到beanDefinition集合中

主要注册HandlerMappings-路径匹配器HandlerAdapters-路径匹配适配器HandlerExceptionResolvers-异常解析器AntPathMatcher-路径解析器UrlPathHelper-请求路径获取帮助类
等beans,提前为mvc做好基础的准备

4、beanFactory根据BeanDefinition生成bean

1、web.xml中配置DispatcherServlet
2、DispatcherServlet#onRefresh()
3、DispatcherServlet#initStrategies()
4、DispatcherServlet#initHandlerMappings()

AbstractApplicationContext#refresh() -->
AbstractApplicationContext#finishBeanFactoryInitialization() -->
DefaultListableBeanFactory#preInstantiateSingletons() -->
AbstractBeanFactory#getBean() -->
AbstractBeanFactory#doGetBean() -->
AbstractAutowireCapableBeanFactory#createBean() -->
AbstractAutowireCapableBeanFactory#doCreateBean() -->
AbstractAutowireCapableBeanFactory#initializeBean() -->
// 前面都是spring的启动过程
AbstractAutowireCapableBeanFactory#invokeInitMethods() -->
RequestMappingHandlerMapping#afterPropertiesSet() -->
// 上面三行都是bean的生命周期过程
// 下面开始是重点
AbstractHandlerMethodMapping#afterPropertiesSet() -->
// 获取所有不以scopedTarget.开头的beanName
AbstractHandlerMethodMapping#initHandlerMethods() -->
// 获取所有带有Controller或者RequestMapping注解的bean的Class对象
AbstractHandlerMethodMapping#processCandidateBean -->
// 找出该Controller下的所有带RequestMapping注解的函数
AbstractHandlerMethodMapping#detectHandlerMethods() -->
// 开始注册映射
RequestMappingHandlerMapping#registerHandlerMethod() -->
// 将映射关系放入AbstractHandlerMethodMapping.mappingRegistry.registry中
AbstractHandlerMethodMapping#registerHandlerMethod()

根据请求url找到对应的controller,并从controller中找到处理请求的方法

DispatcherServlet的初始化

自动装配:在spring-boot-autoconfigure包的spring.factories里面的DispatcherServletAutoConfiguration

@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) {
    xxx
    return dispatcherServlet;
}

getHandler(processedRequest)方法实际上就是从HandlerMapping中找到url和controller的对应关系.这也就是第一个步骤:建立Map<url,Controller>的意义

DispatcherServlet#doDispatch()
// 获取处理器(处理器就是controller)
DispatcherServlet#getHandler()
AbstractHandlerMapping#getHandler()
// 获取请求路径,根据请求路径查找处理器
RequestMappingInfoHandlerMapping#getHandlerInternal()
AbstractHandlerMethodMapping#getHandlerInternal()
// 查找处理器的方法
AbstractHandlerMethodMapping#lookupHandlerMethod()

request参数绑定到方法的形参,执行方法处理请求,并返回结果视图

controller的调用过程

DispatcherServlet#doDispatch()
AbstractHandlerMethodAdapter#handle()
RequestMappingHandlerAdapter#handleInternal()
// 在这里会创建ServletInvocableHandlerMethod,此时已经将controller的函数(HandlerMethod)的参数注入到InvocableHandlerMethod(类变量)中
RequestMappingHandlerAdapter#invokeHandlerMethod()
ServletInvocableHandlerMethod#invokeAndHandle()
// 在此方法中通过反射的方式调用controller中的方法
ServletInvocableHandlerMethod#invokeForRequest()
// 以下是参数处理过程
InvocableHandlerMethod#getMethodArgumentValues()
// 这里会调用getArgumentResolver,根据参数的类型决定使用哪种HandlerMethodArgumentResolver
// 参数处理器是否支持该参数是由supportsParameter方法决定
HandlerMethodArgumentResolverComposite#resolveArgument()
// 例如:参数有RequestBody注解就会使用RequestResponseBodyMethodProcessor参数处理器
RequestResponseBodyMethodProcessor#resolveArgument()
// 调用json工具将参数转换成相应的Object
RequestResponseBodyMethodProcessor#readWithMessageConverters()

返回值的处理过程

ServletInvocableHandlerMethod#invokeAndHandle()
// 选择相应的HandlerMethodReturnValueHandler并执行
HandlerMethodReturnValueHandlerComposite#handleReturnValue()

ModelAndView由返回值处理器ModelAndViewMethodReturnValueHandler处理

参考文章:

springmvc工作原理以及源码分析(基于spring3.1.0) - heavenyes - 博客园 (cnblogs.com)

SpringMVC源码之Handler注册、获取以及请求controller中方法 - 哔哩哔哩 (bilibili.com)

SpringMvc RequestMappingHandlerMapping - 喜欢日向雏田一样的女子啊 - 博客园 (cnblogs.com)

王谷雨

一个苟且偷生的java程序员

文章评论