[1]测试请求地址:http://localhost:8080/car/5/owner/6探究springBoot是如何去解析获取各种类型参数请求的原理
对应的控制器代码
@RestControllerpublic class TestController { @GetMapping("/car/{id}/owner/{username}") public Map
通过全局搜索{ps:快捷键是按两下shift} 查询DispatcherServlet整个类
{ps:DispatcherServlet相当于一个分发器(就是一个Servlet)}
找到doDispatch方法{ps:该方法就相当与做一个调度}
记得打上断点{在WebAsyncManager-Web异步管理器这里(主要用来管理异步请求的处理。)}
[3]开始启动调试启动程序
输入网址
[4]获得执行程序执行链(关于如何映射到方法的){ps:所有的映射地址对应的方法都在这个mappingRegistry注册中心当中}
[5]核心部分--处理器的适配器 ①HandlerAdaptergetHandlerAdapter方法
0 - 支持方法上标注@RequestMapping1 - 支持函数式编程...
适配器判断(通过判断当前传入的是否是Handler类型,来判断是否支持适配器)
最后为其找个一个适配器 RequestMappingHandlerAdapter
②执行目标方法查看内部处理细节(进入RequestMappingHandlerAdapter)
RequestMappingHandlerAdapter-开始执行目标方法了
进入invokeHandlerMethod中查看目标方法如何执行的
我们会发现在可执行方法invocableMethod中设置了一个参数解析器
参数解析器-HandlerMethodArgumentResolverHandlerMethodArgumentResolver参数解析器核心如下
确定将要执行的目标方法的每一个参数的值是什么;
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 方法即可