1.SpringMVC的执行流程
2.SpringBoot请求参数解析原理
1.SpringMVC的执行流程
上一篇博客SpringBoot请求映射原理,我们讲过SpringMVC的执行流程,为了便于学习,每次在这一系列的博客开始前,我都会附上下面这张图。
2.SpringBoot请求参数解析原理
通过上篇博客的学习,我们已经知道了SpringBoot是如何通过请求路径找到对应的执行handler的,那么这篇博客,我们将学习springBoot是如何将请求参数和handler的参数一一对应并执行目标方法的过程。
先说一句话概括结论:SpringBoot通过不同的注解,读取对应的参数并封装。
我们在使用springBoot的时候,经常会在Controller方法上写上以下注解:
@PathVariable
@RequestParam
@RequestBody
...//等等相似的若干注解
我们以下面的controller方法为例,观察参数是如何封装的:
@GetMapping("/test/{id}")
public String test1(@PathVariable String id,
@RequestParam String age)
{
System.out.println(id);
System.out.println(age);
return "ok!";
}
我们依旧在DispatcherServlet的doDispatch方法上打上断点,打在下面这一行:
往里继续执行,我们会发现一行重要的代码,看函数名字就可以知晓,这是执行handler的代码:
继续往里执行,我们会看到很多类的初始化,(可不用详细阅读,抓住主流程即可),不过得记住一个重要的参数,参数解析器,等等会用来解析参数,我们在图上已经标出:
继续执行,我们会发现一个重要方法invokeAndHandle:
我们继续往里看:
可以得出,上面一行根据请求调用了handler的方法, 并且返回了一个参数,看来距离我们要找的代码越来越近了,我们继续往里点击。
根据名字可以得出,我们现在获取了所有参数args,并根据请求参数调用目标handler,我们看看getMethodArgumentValues()方法是如何获取参数的,这就是我们今天要说明的重点:
我们可以看到进行了如下三个步骤:
1.springBoot先获取了handler上的所有形式参数
2.查看handler上的参数是否支持解析
3.若支持解析,则使用参数解析器进行解析。
this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
接下来我们进入suopport方法,我们handler的第一个参数使用的是@PathVariable注解标注:
进入这个方法后,会遍历所有的参数解析器,找到支持当前参数的解析器,可以看到PathVariableMethodArgumentResolver很可能就是我们想到的,我们循环到这个值,并进入方法supportsParameter:
可以看出方法很简单,就是查看这个参数是否标注了PathVariable.class注解,这里我们返回true。(其它的参数解析也是同样的方式,可以自行debug)
参数解析器我们已经得到了,接下来我们看看解析参数的流程:
这里的逻辑也十分简单,大概分成了以下三步:
1.获得handler参数名字
2.根据参数名字从request里拿到参数
3.将这两个参数绑定在一起
其中,参数绑定器WebDataBinder中,有124个conversionService,名为参数转换器服务,可以将request中的字符串参数转换成当前handler参数需要的参数,如日期,整数,字符串等等。
通过这一系列的参数解析,我们就将handler参数和请求参数一一对应了起来。
最后使用反射调用handler的方法。
总结:
1.springBoot里有对应的参数解析器,用来解析Controller上用注解标注的不同参数。
2.springBoot里有若干的参数转换器,用来将请求参数转换成实体类的参数类型。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。