Spring MVC源码之请求映射路径是如何初始化
1.首先解读之前需要了解一点Spring的知识,因为跟Spring牵扯到了,请求映射初始化是从RequestMappingHandlerMapping这个类的afterPropertiesSet()方法开始 。
详解: 先看 RequestMappingHandlerMapping 的继承关系图,需要留意的是它的父类的父类 AbstractHandlerMethodMapping 实现了InitializingBean.(这很重要!)
因为实现了 InitializingBean 类,那么这个类在spring初始化bean的时候会去自动调用 afterPropertiesSet() 方法。
具体内容可以自己去看一下spring的 AbstractAutowireCapableBeanFactory类的createBean()方法
RequestMappingHandlerMapping结构图2.至于 RequestMappingHandlerMapping 这个类调用 afterPropertiesSet() 的时候,它并不是随spring容器启动的时候去调用的,而是等接收第一次请求的时候,初始化springMvc的DispatcherServlet,然后初始化各种类,其中包括RequestMappingHandlerMapping.初始化时候才调用afterPropertiesSet;
二、正文开始
2.1 通过RequestMappingHandlerMapping的afterPropertiesSet()方法追踪到父父类的initHandlerMethods()方法
afterPropertiesSet()2.2.来到父父类 AbstractHandlerMethodMapping 的initHandlerMethods()方法
initHandlerMethods()2.3.接下来走到 AbstractHandlerMethodMapping 类的detectHandlerMethods(beanName) 方法,这里有个函数式方法,我们简称为A
detectHandlerMethods(beanName)2.4.接下来开始,要复杂起来了哦。要去到 MethodIntrospector 类的selectMethods,方法里面的参数传了一个函数式方法作为参数。
下图中又会去调用doWithMethods()方法,传了一个函数式方法,我们称作为B
selectMethods2.5.接下来根据上图,我们继续走,去到ReflectionUtils类里面的doWithMethods(Class<?> clazz, MethodCallback mc, @Nullable MethodFilter mf)方法
其中方法的参数mc是一个函数式接口,方法就是上图的B
doWithMethods2.6,上面通过doWithMethods通过反射拿到类的所有方法,然后遍历。然后把拿到的方法method作为参数去调用 B函数式方法处理
doWithMethods调用了函数方法B函数方法B里面又调用了函数方法A,所以我们又得回头去看detectHandlerMethods(beanName) 里面的函数方法A做了什么
函数方法AgetMappingForMethod2.7. 接下来看 RequestMappingHandlerMapping 类的 getMappingForMethod如何生成RequestMappingInfo
getMappingForMethodcreateRequestMappingInfo方法:
createRequestMappingInfo2.8、生成完RequestMappingInfo之后,要去注册HandlerMethod了
2.9. 接下来注册HandlerMethod方法 registerHandlerMethod方法
我们进到AbstractHandlerMethodMapping 类的register方法
register3.0 最后又要回到开头的AbstractHandlerMethodMapping 的initHandlerMethods()方法 跑完最后2步 就结束整个初始化过程了
结束总结:大概过程就是先去spring容器找到一些带有@RequestMapping或者带有@Controller的类,然后获取controller类上面的@RequestMapping信息和controller类方法的@RequestMapping信息生成RequestMappingInfo,然后组合起来,最后再存储到AbstractHandlerMethodMapping.MappingRegistry内部类里面去