Spring源码学习


  
自己的程序想手工注册RequestMappingHandlerMap ping,让DispatcherServlet处理,又不想影响Spring本身的功能,于是研究Spring源码,以下是分析。


1、RequestMappingHandlerMap ping
方法:registerHandlerMethod(Object handler, Method method, Tmapping)
2、因为第三个参数T mapping是泛型,故往方法内部看,有这么一句
HandlerMethod oldHandlerMethod =handlerMethods.get(mapping);
handlerMethods是Map 类型,key也是泛型
3、查找Debug发现:handlerMethods里这个“T”存放的的是RequestMappingInfo类型
4、查看RequestMappingInfo类,主要存放HttpRequest信息,定义:public finalclass RequestMappingInfo implements RequestCondition,但是没找到这个类有set方法,比如可以传人HttpRequest为该类提供信息的方法
5、再回到:registerHandlerMethod(Object handler, Method method, Tmapping),方法
第三个参数就是用来Mapping的东西,所以变换思路,去DispatcherServlet里查找,他是怎么进行Mapping的
6、DispatcherServlet的doService()方法,保存了Request以便随后恢复
7、doDispatch()方法,重点在:mappedHandler =getHandler(processedRequest, false);
8、HandlerExecutionChain getHandler(HttpServletRequest request)方法,返回HandlerExecutionChain,重点在for (HandlerMapping hm :this.handlerMappings)依次调用每一个HandlerMapping的getHandler方法。
9、去看HandlerMapping,他是一个接口,往下找
10,在AbstractHandlerMapping里找到getHandler(HttpServletRequestrequest)方法,不过其调用了getHandlerInternal(request),这是个抽象方法,继续往下。
11、追到AbstractHandlerMethodMap ping找到getHandlerInternal(HttpServletRequestrequest)的具体实现。String lookupPath =getUrlPathHelper().getLookupPathForRequest(request);首先对URL进行了处理,以应对URI和Servletpath不一致的情况,然后调用lookupHandlerMethod。
12、在HandlerMethod lookupHandlerMethod(String lookupPath,HttpServletRequestrequest)里,主要是从urlMap里查询的,这个Map的key是URI,内容是泛型T。
13、如果按照URI在UrlMap里直接找到了mapping(泛型T),则调用addMatchingMappings方法,这里面又调用了getMatchingMapping是一个虚方法,往下找。
14、在RequestMappingInfoHandle rMapping里找到getMatchingMapping(RequestMappingInfoinfo, HttpServletRequest request)方法,发现这里又一次直接把泛型的mapping转换成了RequestMappingInfo类型
15、getMatchingMapping里调用info.getMatchingCondition(request)方法,返回相应HttpRequest的RequestMappingInfo,这里说明mapping泛型所代表的RequestMappingInfo类型,实际上是HttpRequest的变种。
16、RequestMappingInfo里的getMatchingCondition方法,因为一个URI可能对应很多种HttpRequest参数的组合匹配方式,这个方法把所有能匹配上的参数组合放进RequestMappingInfo对象返回。RequestMappingInfo里给每个HttpRequest参数都有一个set(xxxCondition)。
17、接15,AbstractHandlerMethodMap ping的addMatchingMappings方法,new了多个Match,在这里用mapping做条件查询本地的LinkedHash表,获得handlerHethod,把泛型的mapping(实际上是RequestMappingInfo)和HandlerMethod放进Match,再把多个match放进List。
18、lookupHandlerMethod方法,会对结果进行一个排序。如果发现找到的T不唯一,只会用排序的第一个,并且报一个Exception。
19、T在后面做了转换:Match bestMatch =matches.get(0);Match是一个临时对象其中存储了泛型的Mapping(RequestMappingInfo)和HandlerMethod,HandlerMethod内部存储了Object,也就是Bean,和Method类型。
20、发现匹配后,调用了handleMatch(bestMatch.mapping, lookupPath,request);方法,是一个虚方法,去子类找。
21、在RequestMappingInfoHandle rMapping的handleMatch(RequestMappingInfoinfo, String lookupPath, HttpServletRequestrequest)里,第一个参数是RequestMappingInfo类型,不是泛型T。这个方法里处理了有关pattern的一些事情,不知道是干什么用的。
22、lookupHandlerMethod方法返回了bestMatch.handlerMethod。
23、回顾一下,DispatcherServlet查询Handlermethod过程并没有使用Request、Mapping或者RequestMappingInfo之类的东西,只是用URI就可以返回HandlerMethod。传给RequestMappingInfoHandle rMapping的handleMatch方法的mapping只是用来做了一些pattern处理(不知道什么用处)。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值