欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

SpringBoot原理探究——各种类型参数请求原理

时间:2023-07-08

探究springBoot是如何去解析获取各种类型参数请求的原理

[1]测试请求地址:http://localhost:8080/car/5/owner/6

对应的控制器代码

@RestControllerpublic class TestController { @GetMapping("/car/{id}/owner/{username}") public Map test(@PathVariable("id") String id, @PathVariable("username") String username) { Map map = new HashMap(); //返回请求路径中的参数 map.put("id", id); map.put("username", username); return map; }}

[2]打断点{启动debug调试}

通过全局搜索{ps:快捷键是按两下shift} 查询DispatcherServlet整个类

{ps:DispatcherServlet相当于一个分发器(就是一个Servlet)}

  找到doDispatch方法{ps:该方法就相当与做一个调度}

记得打上断点{在WebAsyncManager-Web异步管理器这里(主要用来管理异步请求的处理。)}

[3]开始启动调试

启动程序

 输入网址

[4]获得执行程序执行链(关于如何映射到方法的)

 {ps:所有的映射地址对应的方法都在这个mappingRegistry注册中心当中}

[5]核心部分--处理器的适配器 ①HandlerAdapter

 getHandlerAdapter方法

0 - 支持方法上标注@RequestMapping1 - 支持函数式编程...

适配器判断(通过判断当前传入的是否是Handler类型,来判断是否支持适配器)

最后为其找个一个适配器 RequestMappingHandlerAdapter

②执行目标方法

 查看内部处理细节(进入RequestMappingHandlerAdapter)

RequestMappingHandlerAdapter-开始执行目标方法了

进入invokeHandlerMethod中查看目标方法如何执行的

我们会发现在可执行方法invocableMethod中设置了一个参数解析器

参数解析器-HandlerMethodArgumentResolver

HandlerMethodArgumentResolver参数解析器核心如下

确定将要执行的目标方法的每一个参数的值是什么;

SpringMVC目标方法能写多少种参数类型。取决于参数解析器。

HandlerMethodArgumentResolver接口的中的两个方法如下

supportsParameter判断当前解析器是否支持这种参数支持就调用解析方法resolveArgument返回值处理器-HandlerMethodReturnValueHandler

RequestMappingHandlerAdapter-真正执行目标执行方法

如何确定目标方法每一个参数的值(核心代码如下)============InvocableHandlerMethod==========================protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object..、providedArgs) throws Exception { MethodParameter[] parameters = this.getMethodParameters(); if (ObjectUtils.isEmpty(parameters)) { return EMPTY_ARGS; } else { Object[] args = new Object[parameters.length]; for(int i = 0; i < parameters.length; ++i) { MethodParameter parameter = parameters[i]; parameter.initParameterNameDiscovery(this.parameterNameDiscoverer); args[i] = findProvidedArgument(parameter, providedArgs); if (args[i] == null) { if (!this.resolvers.supportsParameter(parameter)) { throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver")); } try { args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); } catch (Exception var10) { if (logger.isDebugEnabled()) { String exMsg = var10.getMessage(); if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) { logger.debug(formatArgumentError(parameter, exMsg)); } } throw var10; } } } return args; }}

挨个判断所有参数解析器哪个支持解析找个参数PS:在得到参数解析器是会先找缓存===================HandlerMethodArgumentResolverComposite==========================@Nullableprivate HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) { HandlerMethodArgumentResolver result = (HandlerMethodArgumentResolver)this.argumentResolverCache.get(parameter); if (result == null) { Iterator var3 = this.argumentResolvers.iterator(); while(var3.hasNext()) { HandlerMethodArgumentResolver resolver = (HandlerMethodArgumentResolver)var3.next(); if (resolver.supportsParameter(parameter)) { result = resolver; this.argumentResolverCache.put(parameter, resolver); break; } } } return result;}

解析找个参数的值调用各自 HandlerMethodArgumentResolver 的 resolveArgument 方法即可

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。