工作机制中分三部来分析springmvc的源代码
- ApplicationContext初始化时建立所有url和controller类的对应关系(用Map保存)
- 根据请求url找到对应的controller,并从controller中找到处理请求的方法
- 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)