当前位置: 首页 > news >正文

免费注册个人网站合肥百度 网站建设

免费注册个人网站,合肥百度 网站建设,陈铭生个人资料简介,wordpress 做下载网一、知识回顾 我们知道#xff0c;接口的参数#xff0c;一般都要配上注解来一起使用。 不同的参数注解#xff0c;决定了传参的方式不同。 为什么会这样#xff1f; 如果让你设计接口参数解析#xff0c;你会怎么做#xff1f; 首先#xff0c;我们知道方法参数是形…一、知识回顾 我们知道接口的参数一般都要配上注解来一起使用。 不同的参数注解决定了传参的方式不同。 为什么会这样 如果让你设计接口参数解析你会怎么做 首先我们知道方法参数是形参。具体的实参是request中带来的。 那么springboot底层是如何将path中的实参与接口的形参对应上的 二、源码解读 首先我们知道接口肯定是归DispatcherServlet类来管理的所以我们直接进入这个类 前面的章节我们已经知道接口入口方法是org.springframework.web.servlet.DispatcherServlet#doDispatch 所以我们进入这个方法进行断点跟踪并分析原理。 DispatcherServlet#doDispatch方法 1、找到对应request的Handler 这里的原理解释在 SpringBoot2请求处理原理分析-请求Path与接口的映射关系(HandlerMapping) 2、找Handler的适配器 mappedHandler.getHandler() 这个已经拿到具体的controller了返回类型是HandlerMehod类型 那么为什么不直接就反射调用了还弄个适配器干啥 我们进入getHandlerAdapter方法 这里的适配器有4种 我们在看看适配器结构 它是一个接口有三个方法。 它有以下几个实现类 这里我们会发现实现类有6个为什么handlerAdapters变量只有4个了 我们继续看源码会发现是通过DispatcherServlet.properties配置好的。 D:/app/maven/repository/org/springframework/spring-webmvc/5.2.9.RELEASE/spring-webmvc-5.2.9.RELEASE.jar!/org/springframework/web/servlet/DispatcherServlet.properties 继续往下看 通过getHandlerAdapter方法我们可以看出Adapters是通过supports方法来确定具体哪个适配器来处理。 supports的具体逻辑就不看了因为每个实现的adapter判断逻辑不通。 也就是说getHandlerAdapter方法循环遍历四个adapters通过adapter的supports方法找到了handler对应的HandlerAdapter类。 3、通过适配器处理controller接口参数 我们常用的是RequestMapping类型的接口注解。 所以这里我主要解读一下org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter 这里我们可以看出ha.handle是具体的哪个adapter来实现的从而进入对应的实现类里进行处理。 我这里肯定是进入RequestMappingHandlerAdapter类中看具体逻辑。 3.1、查看RequestMappingHandlerAdapter适配器处理逻辑 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#invokeHandlerMethod 这里设置参数解析器和返回值处理器。 有26个参数解析器和15个返回值处理器 26个参数解析器代码位置 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultArgumentResolvers 注意ServletModelAttributeMethodProcessor解析器添加了2次 private ListHandlerMethodArgumentResolver getDefaultArgumentResolvers() {ListHandlerMethodArgumentResolver resolvers new ArrayList(30);// Annotation-based argument resolutionresolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));resolvers.add(new RequestParamMapMethodArgumentResolver());resolvers.add(new PathVariableMethodArgumentResolver());resolvers.add(new PathVariableMapMethodArgumentResolver());resolvers.add(new MatrixVariableMethodArgumentResolver());resolvers.add(new MatrixVariableMapMethodArgumentResolver());resolvers.add(new ServletModelAttributeMethodProcessor(false));resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));resolvers.add(new RequestHeaderMapMethodArgumentResolver());resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));resolvers.add(new SessionAttributeMethodArgumentResolver());resolvers.add(new RequestAttributeMethodArgumentResolver());// Type-based argument resolutionresolvers.add(new ServletRequestMethodArgumentResolver());resolvers.add(new ServletResponseMethodArgumentResolver());resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));resolvers.add(new RedirectAttributesMethodArgumentResolver());resolvers.add(new ModelMethodProcessor());resolvers.add(new MapMethodProcessor());resolvers.add(new ErrorsMethodArgumentResolver());resolvers.add(new SessionStatusMethodArgumentResolver());resolvers.add(new UriComponentsBuilderMethodArgumentResolver());// Custom argumentsif (getCustomArgumentResolvers() ! null) {resolvers.addAll(getCustomArgumentResolvers());}// Catch-allresolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));resolvers.add(new ServletModelAttributeMethodProcessor(true));return resolvers;}15个返回值处理器代码位置 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#getDefaultReturnValueHandlers private ListHandlerMethodReturnValueHandler getDefaultReturnValueHandlers() {ListHandlerMethodReturnValueHandler handlers new ArrayList(20);// Single-purpose return value typeshandlers.add(new ModelAndViewMethodReturnValueHandler());handlers.add(new ModelMethodProcessor());handlers.add(new ViewMethodReturnValueHandler());handlers.add(new ResponseBodyEmitterReturnValueHandler(getMessageConverters(),this.reactiveAdapterRegistry, this.taskExecutor, this.contentNegotiationManager));handlers.add(new StreamingResponseBodyReturnValueHandler());handlers.add(new HttpEntityMethodProcessor(getMessageConverters(),this.contentNegotiationManager, this.requestResponseBodyAdvice));handlers.add(new HttpHeadersReturnValueHandler());handlers.add(new CallableMethodReturnValueHandler());handlers.add(new DeferredResultMethodReturnValueHandler());handlers.add(new AsyncTaskMethodReturnValueHandler(this.beanFactory));// Annotation-based return value typeshandlers.add(new ModelAttributeMethodProcessor(false));handlers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(),this.contentNegotiationManager, this.requestResponseBodyAdvice));// Multi-purpose return value typeshandlers.add(new ViewNameMethodReturnValueHandler());handlers.add(new MapMethodProcessor());// Custom return value typesif (getCustomReturnValueHandlers() ! null) {handlers.addAll(getCustomReturnValueHandlers());}// Catch-allif (!CollectionUtils.isEmpty(getModelAndViewResolvers())) {handlers.add(new ModelAndViewResolverMethodReturnValueHandler(getModelAndViewResolvers()));}else {handlers.add(new ModelAttributeMethodProcessor(true));}return handlers;}执行并处理 org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle 通过这个名字我们也可以看出这里invokeForRequest就是已经处理完请求了。 进入invokeForRequest 关键代码找到了getMethodArgumentValues获取方法参数值。 org.springframework.web.method.support.InvocableHandlerMethod#getMethodArgumentValues protected Object[] getMethodArgumentValues(NativeWebRequest request, Nullable ModelAndViewContainer mavContainer,Object... providedArgs) throws Exception {MethodParameter[] parameters getMethodParameters();if (ObjectUtils.isEmpty(parameters)) {return EMPTY_ARGS;}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) {continue;}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 ex) {// Leave stack trace for later, exception may actually be resolved and handled...if (logger.isDebugEnabled()) {String exMsg ex.getMessage();if (exMsg ! null !exMsg.contains(parameter.getExecutable().toGenericString())) {logger.debug(formatArgumentError(parameter, exMsg));}}throw ex;}}return args;}首先我们看下参数解析器 规范 有两个方法 supportsParameter用来判断是否支持解析 resolveArgument用来进行具体的解析操作 这里用了设计模式中的组合模式 HandlerMethodArgumentResolverComposite实现了HandlerMethodArgumentResolver接口 然后在该类中循环遍历是否有解析器可以处理当前参数如果有具体怎么解析。 关键代码行 args[i] this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); 通过断点我们可以看出此时args[i]被赋值了。 继续进入this.resolvers.resolveArgument查看逻辑 99行获取形参名108行才是给形参赋值。 所以在108行之前都是解析接口方法形参。 我们在看下resolveName方法可以看到这个方法有很多具体的实现类。 我这里以PathVariable为例子。 org.springframework.web.servlet.mvc.method.annotation.PathVariableMethodArgumentResolver#resolveName 可以看出给形参名的值是从request中获取到的。这样形参和实参就对应上了。 那么这里的request.getAttribute是如何处理好的这里没有说明。 网上说是通过org.springframework.web.util.UrlPathHelper类实现的。 具体有兴趣的同学自己去研究一下。 那么到这里源码逻辑就差不多结束了。 三、逻辑梳理 首先请求接口进入DispatcherServlet#doDispatch方法 先从handlerMapping中获取具体的handler即找到具体是哪个controller来处理请求。 而handlerMapping类型默认配置了5种。 找到对应的handler后在找到对应的handlerAdapter handlerAdapters适配器类型默认配置了4种。 再然后通过具体的handlerAdapter来解析方法参数 而解析方法参数用到了参数解析器argumentResolvers 这里参数解析器配置了26种。 并且用了组合模式缓存来优化性能。 遍历循环参数解析器找到对应参数的解析器后 在通过接口方法的形参信息如参数类型参数名称参数注解等。 进行具体的参数解析并从request中获取实参值赋值给形参完成参数解析。
http://www.dnsts.com.cn/news/55673.html

相关文章:

  • 深圳网站建设注册怎么看网站做的外链
  • 网站如何做seo优化教程建设网上银行网站
  • 网站托管方式导航网站搭建
  • 软件手机站谷歌amp wordpress
  • 外贸网站案例纯净软件网站推荐
  • 网站建设和系统集成建设网站实训报告书
  • 网站响应式布局白百度一下你就知道
  • 北京做网站设计招聘诸城网站设计
  • 有哪些做网站的公司小企业网站推广
  • 自己创办网站啥前端框架可以做网站首页
  • 网站图片防盗连怎么做购买马来网站域名
  • 定西建设厅网站北京网站优化平台
  • 国外做mg动画的网站大全做网站要钱嘛
  • 有了php源码怎么做网站深圳网络营销十年乐云seo专家
  • 凡科建网站余姚网站建设企业
  • 旅游网站策划书拟定网站优化方案
  • 山西响应式网站建设设计杭州市建设工程信用网
  • 网站上的广告是怎么做的青岛气象站建站时间
  • 南宁网站建设方案服务太原市建设厅网站
  • 企业创建网站的途径深圳新星公司官网
  • 怎么建立网站网址百度渠道开户哪里找
  • 广州模板建站系统wordpress get users
  • 莘县网站建设电话广州开发网站
  • 名雕装饰公司的口碑怎样aso优化软件
  • 哪些网站可以做店淘客杭州本地网站
  • 国外商城网站设计seo公司官网
  • 莆田制作网站企业公司免费网页怎么制作
  • 外贸建站 厦门wordpress自动评论
  • 网站什么做的企业所得税怎么算利润
  • 可以做免费广告的网站有哪些wordpress 360 vr