Spring MVC源码之请求映射路径是如何初始化

2019-04-25  本文已影响0人  我我我不是明

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

selectMethods

2.5.接下来根据上图,我们继续走,去到ReflectionUtils类里面的doWithMethods(Class<?> clazz, MethodCallback mc, @Nullable MethodFilter mf)方法 

其中方法的参数mc是一个函数式接口,方法就是上图的B

doWithMethods

2.6,上面通过doWithMethods通过反射拿到类的所有方法,然后遍历。然后把拿到的方法method作为参数去调用 B函数式方法处理

doWithMethods调用了函数方法B

函数方法B里面又调用了函数方法A,所以我们又得回头去看detectHandlerMethods(beanName) 里面的函数方法A做了什么

函数方法AgetMappingForMethod

2.7. 接下来看 RequestMappingHandlerMapping 类的 getMappingForMethod如何生成RequestMappingInfo

getMappingForMethod

createRequestMappingInfo方法:

createRequestMappingInfo

2.8、生成完RequestMappingInfo之后,要去注册HandlerMethod了

2.9. 接下来注册HandlerMethod方法 registerHandlerMethod方法

我们进到AbstractHandlerMethodMapping 类的register方法

register

3.0 最后又要回到开头的AbstractHandlerMethodMapping 的initHandlerMethods()方法 跑完最后2步 就结束整个初始化过程了

结束

总结:大概过程就是先去spring容器找到一些带有@RequestMapping或者带有@Controller的类,然后获取controller类上面的@RequestMapping信息和controller类方法的@RequestMapping信息生成RequestMappingInfo,然后组合起来,最后再存储到AbstractHandlerMethodMapping.MappingRegistry内部类里面去

上一篇 下一篇

猜你喜欢

热点阅读