之前一直好奇为什么我们写上@RequestMapping就能访问我们的程序接口,研究源码发现是spring在启动的时候就已经把我们的所有包含@RequestMapping的类和方法上的路径拼接好放在一个map缓存中,后面我们通过请求url的时候会直接从缓存中获取,然后匹配,今天就带大家看一下springmvc是如何将我们写的@RequestMapping上的路径注册给程序并放入缓存中的,话不多说,上源码。
spring在启动的时候会初始化AbstractHandlerMethodMapping类,他实现了InitializingBean的接口
所以在初始化的时候会调用afterPropertiesSet这个方法,然后调用initHandlerMethods方法
扫描 ApplicationContext 中的 bean,检测和注册处理程序方法。
getCandidateBeanNames这个方法会获取所有候选的bean名称,也就是容器加载的时候加载的所有bean
然后遍历所有的bean,执行processCandidateBean这个方法,也就是处理候选的bean,点进这个方法
我们会看到在if判断中有isHandler的方法,具体实现类在RequestMappingHandlerMapping类中,点进去发现
这块会有两个判断,一个是判断类上有没有标注@Controller注解,另一个是判断有没有标注@RequestMapping注解,看到这是不是豁然开朗,这就是为什么我们平时标注这两个注解springmvc就会找到我们的路径的原因,继续往下看
如果标了这两个任意一个注解,就会进入detectHandlerMethods方法,追进去我们看
其中selectMethods这个方法是查询我们类里面的所有方法。
getMappingForMethod是获取方法的映射,在这一方法中会将类上的uri和方法上的uri拼接起来,并封装一个RequestMappingInfo对象返回
最后会遍历methods这个属性,调用registerHandlerMethod方法,具体在RequestMappingHandlerMapping类中,注册处理程序方法
调用父类方法
然后执行register注册方法,在这个方法中我们会发现有一个this.registry.put()的操作
这个register对象,点上去发现时一个Map对象,由此可得出,我们所有的路径uri包装对象都会存放在这个map对象中,等我们在真正执行mvc请求时,就会从这个里面获取有没有我们请求的路径
在这个registry对象中,我们会发现它存储了我们所有请求的请求方式,uri,以及具体的方法所在的类路径等等信息。
至此,我们就将spring在启动过程中将所有的uri加载放入缓存的这一步骤分析完成,感兴趣的朋友可以自己断点看一下,后续有时间会更新一下mvc具体的执行流程。
谢谢大家,有问题可以在下方留言。
原创不易,多多点赞~~~~