【springboot】请求处理-源码分析-各种参数类型解析原理

同样来到请求处理的核心类DispactcherServlet,再次debug。

主要就是两个关键:一是handler 二是adapter (request->mappedHandler->handlerAdapter)最后的mv对象调用handle方法:

先是取得handler(mappedHandler),类型为HandleMethod(上一篇文章已提到过):  

执行到这一行得到一个HandlerAdapter对象,也就是为前文取得的handler寻找一个适配器(adapter):(一)HandlerAdapter有四种类型:

RequestMappingHandlerAdapter见名知意,就是支持在方法上标注@RequestMapping的。

HandlerFunctionAdapter支持函数式编程。

也可以自定义handlerAdapter,但是需要通过supports方法声明可用:

debug进入supports方法的具体实现:

只要handler是HandlerMethod的实例(类型),都可以将handler与adapter配合。而我们的handler在前面已经evaluate过可以看出是HandlerMethod的类型。

可见,默认匹配的adapter是RequestMappingHandlerAdapter类型的。 

// actually avoke the handler

将处理过的request,response和handler都传入handlerAdapter的handle方法中,才真正启动handler。

而先进入mappedHandler.getHandler()方法取得handler(前文已有介绍不再赘述)。

再forceInto 这个handle方法: 

(二)执行核心方法。

如果是RequestMappingHandlerAdapter类型的话,对应handle方法中核心调用的是RequestMappingHandlerAdapter类的handleInternal方法:

进入handlerInternal方法: 

mav = this.invokeHandlerMethod(request, response, handlerMethod); //执行目标方法 

进入invokeHandleMethod核心方法:

(三)参数解析器(XxxMethodArgumentResolvers)

从名字上可以看出来,对应的是@RequestParam,@PathVariable,@MatrixVariable,@RequestHeader......

先要判断是否支持当前这种参数。只有supportsParameter为true才可以继续调用参数解析器:

 

(四)返回值处理器(HandlerMethodReturnValueHandler)

参照(三)参数解析器的思路易知同样地得到HandlerMethodReturnValueHandler:

 

参数解析器是对应不同的方法参数,而返回值处理器是对应不同的返回值。

封装好这些对应的解析器和处理器后的invocableMethod再调用invokeAndHandle方法:

forceInto:

回顾一下我们对应的controller的请求方法:也在该方法首行打下断点,

在首行两句打下断点,通过放行首行判断哪一行的方法才是真正执行controller请求方法的。

通过调试发现invokeForRequest方法才是核心的执行方法:

他在这个类中

进入invokeForRequest方法中:

getMethodArgumentValues获取方法参数值:

 因为parameter是已经被封装好的包含参数类型等的参数名信息。

 首先根据getMethodParameters方法得到controller方法的参数parameters,然后根据providedArgs(就是方法头的形参)和findProvidedArgument方法得到每一个位置i的参数值,存入args数组中: 

如果进入getMethodArgumentValues方法一步步debug,会发现就是这样一个一个值取得然后存入args数组中的。(当然,如果一开始获得的参数列表parameters为空,那就不必再继续下去了)

(1)解析器要先判断是否支持该类型的参数,this.resolvers.supportsParameter方法实现

进入supportsParameter方法:

其实就是迭代列表逐个匹配解析器,直到找到合适的resolver。

var3是所有argumentResolvers的值的一个迭代器。

最后getArgumentResolver方法得到匹配的resolver,这里是PathVariable类型的:

然后才能进行下一步的参数解析:

(2)核心的解析参数值的方法——this.resolvers.resolveArgument

走else的逻辑,调用另一个resolveArgument方法: 

查看resolveName方法:

每解析到一个参数后,都会回到RequestMappingHandlerAdapter中更新我们的请求,更新完成: 

至此,已经完成在springboot中处理请求——解析controller方法参数部分的源码简析。

(ps...读源码真的好痛苦)

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值