目录
- 简介
- doDispatch() 源码解析
- this.mappingRegistry
简介
在DispatcherServlet类中, 最关键的就是doDispatch()这个方法, 每一次请求都需要经过这个方法, 对每个请求进行转发, 通过反射调用对应的方法
doDispatch() 源码解析
可以看到最关键的代码就是1047行, 根据请求对象, 获取到对应handler处理链(HandlerExecutionChain对象), 这里需要注意的是返回的不是一个handler, 而是一个链, 里面包含了请求对应的过滤器集合, 进入方法看一下
可以看到, 有如歌handlermapping(在初始化时候添加到集合里面的), 根据不同类型的handlermapping获取HandlerExecutionChain, 这里我们只是普通请求, 使用的就是第一个RequestMappingHandlerMapping, 进入方法查看
继续进入
可以看到, 最关键的代码就是这一个方法了, 首先用initLookupPath方法获取到请求的地址, 之后再379行根据地址, 获取到对应的HandlerMethod对象, 进入379行
399行: 根据url, 获取到对应的集合, 集合里面对应的类型是RequestMappingInfo类型, 在这里this.mappingRegistry这个对象非常关键, 所有的映射关系都存在这个对象里面, 后面会说一下这个对应的初始化流程
400-402行 : 过滤上面集合里面的RequestMappingInfo对象, 存到matches集合中
407行 : 匹配唯一的Match对象
435行 : 获取对应的HandlerMehtod
到此我们就获取到了这个请求对应的处理器, 之后还需要获取该处理器对应的拦截器链路,即可
516行就是获取拦截器链路, 就不具体展开了 源码非常简单, 自己查看
this.mappingRegistry
接下来具体说一下this.mappingRegistry这个对象, 我们刚才有说这个对象包含所有的映射关系, 让我们来看一下他是如何初始化的
MappingRegistry类是AbstractHandlerMethodMapping类的一个内部类, 它里面最关键的数据包括两个
pathLookup : 是一个map, key是请求路径, value是一个requestMappingInfo对象
registry : 是一个map, key是requestMappingInfo对象, value是MappingRegistration对象, MappingRegistration里面包含HandlerMethod属性
可以看到,AbstractHandlerMethodMapping 类实现了InitializingBean接口, 这时候我们需要看具体的实现方法afterPropertiesSet()
可以猜测, 初始化就是在这个方法中完成的, 进入
222行遍历所有的bean,去执行224行的代码, 进入
只有265行有具体的操作, 看一下什么样的bean才满足264行的条件
类上必须有Controller注解获取RequestMapping注解才可以
返回到上一级, 进入到265行, 看一下进行了哪些操作
280-289行 : 根据类的全限定名, 获取类下的带有RequestMapping注解的方法存入到一个map, key : Method对象, value : RequestMappingInfo对象
298行 : 将map里面的信息赋值到MappingRegistry类中
下一篇再继续解析获取到处理器链路之后, doDispatch()这个方法还进行了哪些操作