SpringMvc源码解读笔记
工作机制中分三部来分析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)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律