20.Spring Boot各种类型参数解析原理
我在 Spring Boot请求映射原理 已经分析了为何从doDispatch开始分析每个请求,有疑问的小伙伴可以去看看
参数处理原理
HandlerMapping中找到能处理请求的Handler(Controller.method())
为当前Handler 找一个适配器 HandlerAdapter; RequestMappingHandlerAdapter
适配器执行目标方法并确定方法参数的每一个值
1.HandlerAdapter
进入getHandlerAdapter方法
默认四种处理器适配器,
0 - 支持方法上标注@RequestMapping
1 - 支持函数式编程的
查看是否支持当前的适配器
找到适配器之后查看当前方法是否是Get方法,中间跳过
2.执行目标方法
核心是
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
进入handle方法
继续进入
相当于目标方法的真正执行是在RequestMappingHandlerAdapter类中,其核心是
invokeHandlerMethod(request, response, handlerMethod)
即执行目标方法
进入
得到关键字argumentResolvers
3.参数解析器
确定将要执行的目标方法的每一个参数的值是什么;
SpringMVC目标方法能写多少种参数类型。取决于参数解析器。
和我如下的注释对应了起来
参数解析器实质是一个接口,如果第一个方法判断支持就调用第二个方法解析
4.返回值处理器
参数解析器,返回值处理器都提前放在invocableMethod中,
最终来到invokeHandlerMethod方法的invokeAndHandle处
进去该方法里面,
invokeForRequest:执行当前请求
如果放行,就会来到目标方法,进到controller,然后到达
setResponseStatus(webRequest),所以重点在 invokeForRequest
5、如何确定目标方法每一个参数的值
进入invokeForRequest方法
args里已经确定了方法参数值 ,
进入getMethodArgumentValues查看如何获取参数值
先是获取到方法参数的详细信息
然后new一个空的args数组,在for循环里面进行赋值,进入循环,判断当前解析器是否支持该参数,resolvers是26个解析器,
5.1、挨个判断所有参数解析器那个支持解析这个参数
进入supportsparameter方法,
可以发现是遍历这26个参数解析器
进入第一个解析器的supportsparameter方法,判断的方式很简单,即有没有标注RequestParam注解,没有继续循环下一个,如果找到就加入缓存中,方便下一次寻找
5.2、解析这个参数的值
进入该方法
拿到对应的解析器,是从缓存中拿的,因为在5.1中已经放入了,
进去resolver.resolveArgument查看如何解析
首先拿到这两个值
resolveName解析参数的名字
最终得到id为3
6.反射调用目标方法
doInvoke则是通过反射调用我们的目标方法