OpenFegin源码分析-2

FeignClientFactoryBean 分析

1、类图
实现了spring InitlizaingBean接口的 afterPropertiest()方法
实现了FactoryBean 实现了里面getObject()方法
实现了ApplicationContextAware接口 里面的setApplicationContext()方法

在这里插入图片描述
2、afterPropertiest()方法

@Override
public void afterPropertiesSet() throws Exception {
   Assert.hasText(this.contextId, "Context id must be set");
   Assert.hasText(this.name, "Name must be set");
}

3、getObject()方法

@Override
public Object getObject() throws Exception {
   return getTarget();
}
<T> T getTarget() {
    //从application中获取FeignContext通过FeignAutoConfiguration自动装配导入的
   FeignContext context = this.applicationContext.getBean(FeignContext.class);
   //调用feign方法获取feign的budiler构造器 并设置feign的相关属性 如level,retryer,errorDecoder,options 以及RequestInterceptor和decode404配置
   Feign.Builder builder = feign(context);
   //判断url属性是否空 为空的话创建 loadBalance负载均衡客户端
   if (!StringUtils.hasText(this.url)) {
       //判断name属性是否为http开头 
      if (!this.name.startsWith("http")) {
          //url属性为 http://serviceId 格式
         this.url = "http://" + this.name;
      }
      else {
         this.url = this.name;
      }
      //url属性path处理 1、去除空格 2、如果不是以/开头添加/ 3、结尾如果是/ 去掉/结尾
      this.url += cleanPath();
      //构建loadBlacnce客户端
      return (T) loadBalance(builder, context,
            new HardCodedTarget<>(this.type, this.name, this.url));
   }
   //如果url不为空 并且url不是http开头 url重新赋值 前面添加http://
   if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) {
      this.url = "http://" + this.url;
   }
     //url属性path处理 1、去除空格 2、如果不是以/开头添加/ 3、结尾如果是/ 去掉/结尾
   String url = this.url + cleanPath();
   //获取客户端
   Client client = getOptional(context, Client.class);
   if (client != null) {
      if (client instanceof LoadBalancerFeignClient) {
         //不是负载平衡,因为我们有一个url,但是ribbon在类路径上,所以unwrap
         //LoadBalancerFeignClient
         client = ((LoadBalancerFeignClient) client).getDelegate();
      }
      //设置feign的client属性
      builder.client(client);
   }
   //获取 targeter
   Targeter targeter = get(context, Targeter.class);
   return (T) targeter.target(this, builder, context,
         new HardCodedTarget<>(this.type, this.name, url));
}
protected Feign.Builder feign(FeignContext context) {
    //获取FeignLoggerFactory 从FeignContext中获取 最终会调到夫类 NamedContextFactory 会根据每个 contectId创建一个
   FeignLoggerFactory loggerFactory = get(context, FeignLoggerFactory.class);
   //创建日志类 没有配置默认Slf4jLogger
   Logger logger = loggerFactory.create(this.type);
   //构建feign.builder从NamedContextFactory中的AnnotationConfigApplicationContext中获取
   Feign.Builder builder = get(context, Feign.Builder.class)
   //设置日志类
         .logger(logger)
        //PageableSpringEncoder 在FeignClientsConfiguration中注入
         .encoder(get(context, Encoder.class))
         //OptionalDecoder     在FeignClientsConfiguration中注入        
         .decoder(get(context, Decoder.class))
         //SpringMvcContract  在FeignClientsConfiguration中注入   
         .contract(get(context, Contract.class));
   //配置feign属性日志level,retryer,errorDecoder,options 以及RequestInterceptor和decode404配置
   configureFeign(context, builder);
   return builder;
}
protected void configureFeign(FeignContext context, Feign.Builder builder) {
    //从容器中获取FeignClientProperties通过FeignAutoConfiguration 自动装类导入配置
   FeignClientProperties properties = this.applicationContext
         .getBean(FeignClientProperties.class);
   if (properties != null) {
       //创建后默认为true
      if (properties.isDefaultToProperties()) {
          //从配置类中设置配置 根据contextId从获取bean配置
         configureUsingConfiguration(context, builder);
         //从配置文件中 获取Default配置
         configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder);
         //根据contextId获取Properties进行配置
         configureUsingProperties(properties.getConfig().get(this.contextId),builder);
      }
      else {
          //设置properties中Default配置
         configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()),builder);
         //设置propertiest中单个服务配置
         configureUsingProperties(properties.getConfig().get(this.contextId),builder);
         //使用spring容器中的bean配置
         configureUsingConfiguration(context, builder);
      }
   }
   else {
       //如果获取的到的properties不为空 直接通过配置类设置
      configureUsingConfiguration(context, builder);
   }
}

从容器中获取

protected void configureUsingConfiguration(FeignContext context,
      Feign.Builder builder) {
          //获取日志级别
   Logger.Level level = getOptional(context, Logger.Level.class);
   if (level != null) {
      builder.logLevel(level);
   }
   //获取重试 
   Retryer retryer = getOptional(context, Retryer.class);
   if (retryer != null) {
      builder.retryer(retryer);
   }
   //获取错误编码器默认 null
   ErrorDecoder errorDecoder = getOptional(context, ErrorDecoder.class);
   if (errorDecoder != null) {
      builder.errorDecoder(errorDecoder);
   }
   //获取超时配置 默认链接超时10s 读超时60s
   Request.Options options = getOptional(context, Request.Options.class);
   if (options != null) {
      builder.options(options);
   }
   //获取feign拦截器配置
   Map<String, RequestInterceptor> requestInterceptors = context
         .getInstances(this.contextId, RequestInterceptor.class);
   if (requestInterceptors != null) {
      builder.requestInterceptors(requestInterceptors.values());
   }
   //设置404
   if (this.decode404) {
      builder.decode404();
   }
}
protected void configureUsingProperties(
      FeignClientProperties.FeignClientConfiguration config,
      Feign.Builder builder) {
   if (config == null) {
      return;
   }
   //判断如果日志级别不为空配置日志级别
   if (config.getLoggerLevel() != null) {
      builder.logLevel(config.getLoggerLevel());
   }
     //判断链接超时时间和读超时时间不为空设置
   if (config.getConnectTimeout() != null && config.getReadTimeout() != null) {
      builder.options(new Request.Options(config.getConnectTimeout(),
            config.getReadTimeout()));
   }
   //配置retryer重试不为空配置
   if (config.getRetryer() != null) {
      Retryer retryer = getOrInstantiate(config.getRetryer());
      builder.retryer(retryer);
   }
   //判断错误编码不为空 进行设置
   if (config.getErrorDecoder() != null) {
      ErrorDecoder errorDecoder = getOrInstantiate(config.getErrorDecoder());
      builder.errorDecoder(errorDecoder);
   }
   //拦截器不为空设置
   if (config.getRequestInterceptors() != null
         && !config.getRequestInterceptors().isEmpty()) {
      // 这将把请求拦截器添加到构建器中,而不是替换现有的
      for (Class<RequestInterceptor> bean : config.getRequestInterceptors()) {
         RequestInterceptor interceptor = getOrInstantiate(bean);
         builder.requestInterceptor(interceptor);
      }
   }
   //404页面不为空设置
   if (config.getDecode404() != null) {
      if (config.getDecode404()) {
         builder.decode404();
      }
   }
   if (Objects.nonNull(config.getEncoder())) {
      builder.encoder(getOrInstantiate(config.getEncoder()));
   }
   if (Objects.nonNull(config.getDecoder())) {
      builder.decoder(getOrInstantiate(config.getDecoder()));
   }
   //设置契约为springmvc 默认实现
   if (Objects.nonNull(config.getContract())) {
      builder.contract(getOrInstantiate(config.getContract()));
   }
}
protected <T> T loadBalance(Feign.Builder builder, FeignContext context,
      HardCodedTarget<T> target) {
          //获取client 接口实现类型默认实现为 LoadBalancerFeignClient
   Client client = getOptional(context, Client.class);
   if (client != null) {
       //构建client
      builder.client(client);
      //获取targeter 有2种 1、DefaultTargeter 2、HystrixTargeter 如果引入Hystrix类则为HystrixTargeter
      Targeter targeter = get(context, Targeter.class);
      //最终获取到HardCodedTarget
      return targeter.target(this, builder, context, target);
   }
   throw new IllegalStateException(
         "No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon?");
}

DefaultTargeter和HystrixTargeter 注入条件

@Configuration
@ConditionalOnClass(name = "feign.hystrix.HystrixFeign")
protected static class HystrixFeignTargeterConfiguration {
   @Bean
   @ConditionalOnMissingBean
   public Targeter feignTargeter() {
      return new HystrixTargeter();
   }
}
@Configuration
@ConditionalOnMissingClass("feign.hystrix.HystrixFeign")
protected static class DefaultFeignTargeterConfiguration {
   @Bean
   @ConditionalOnMissingBean
   public Targeter feignTargeter() {
      return new DefaultTargeter();
   }
}

@Override
public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign,
      FeignContext context, Target.HardCodedTarget<T> target) {
          //判断是否为feign.hystrix.HystrixFeign.Builder类型直接 使用feign.target方法创建动态代理
   if (!(feign instanceof feign.hystrix.HystrixFeign.Builder)) {
      return feign.target(target);
   }
   //如果不是强转类型 设置feign属性 使用feign.target方法创建动态代理
   feign.hystrix.HystrixFeign.Builder builder = (feign.hystrix.HystrixFeign.Builder) feign;
   String name = StringUtils.isEmpty(factory.getContextId()) ? factory.getName()
         : factory.getContextId();
   SetterFactory setterFactory = getOptional(name, context, SetterFactory.class);
   if (setterFactory != null) {
      builder.setterFactory(setterFactory);
   }
   Class<?> fallback = factory.getFallback();
   if (fallback != void.class) {
      return targetWithFallback(name, context, target, builder, fallback);
   }
   Class<?> fallbackFactory = factory.getFallbackFactory();
   if (fallbackFactory != void.class) {
      return targetWithFallbackFactory(name, context, target, builder,
            fallbackFactory);
   }
   return feign.target(target);
}
public <T> T target(Target<T> target) {
    //builde()方法 创建同步执行的方法处理器工厂,放入到名称解析处理器中 创建反射的ReflectiveFeign对象
    //调用ReflectiveFeign.newInstance(target) 里面包括对fegin接口校验以及feign注解的解析
  return build().newInstance(target);
}
public Feign build() {
    //创建同步执行的方法处理器工厂
  SynchronousMethodHandler.Factory synchronousMethodHandlerFactory =
      new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors, logger,
          logLevel, decode404, closeAfterDecode, propagationPolicy);
          //创建名称解析处理器
  ParseHandlersByName handlersByName =
      new ParseHandlersByName(contract, options, encoder, decoder, queryMapEncoder,
          errorDecoder, synchronousMethodHandlerFactory);
          //创建反射的feign
  return new ReflectiveFeign(handlersByName, invocationHandlerFactory, queryMapEncoder);
}

最终会走到 feign反射类 ReflectiveFeign类的newInstance方法里面 创建动态代理

@Override
public <T> T newInstance(Target<T> target) {
    //校验并解析feign类以及方法的@RequestMapping注解 并解析参数的注解,以及返回值类型 
    //再加上feign的配置信息 组装成一个key为 类#方法名(参数)  value为SynchronousMethodHandler类型的map
  Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);
  Map<Method, MethodHandler> methodToHandler = new LinkedHashMap<Method, MethodHandler>();
  List<DefaultMethodHandler> defaultMethodHandlers = new LinkedList<DefaultMethodHandler>();
  //下面循环主要是为 1、获取默认方法下面会绑定代理类, 2、nameToHandler 转换成 methodToHandler
  for (Method method : target.type().getMethods()) {
      //如果method归属于object类型跳过
    if (method.getDeclaringClass() == Object.class) {
      continue;
    } 
    //如果method是默认的 添加到 defaultMethodHandlers 和methodToHandler 中
    else if (Util.isDefault(method)) {
      DefaultMethodHandler handler = new DefaultMethodHandler(method);
      defaultMethodHandlers.add(handler);
      methodToHandler.put(method, handler);
    } 
    else {
        //将nameToHandler中的key由string类型转变成method类型 value是 SynchronousMethodHanlder
      methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));
    }
  }
  //创建出来一个FeignInvocationHandler
  InvocationHandler handler = factory.create(target, methodToHandler);
  //创建动态代理类
  T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),
      new Class<?>[] {target.type()},
       handler);
   //为默认方法绑定 代理类
  for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
    defaultMethodHandler.bindTo(proxy);
  }
  return proxy;
}

ParseHandlersByName的apply方法

public Map<String, MethodHandler> apply(Target key) {
    //解析所有的类 方法以及参数 返回值 返回list
  List<MethodMetadata> metadata = contract.parseAndValidatateMetadata(key.type());
  //创建结果map
  Map<String, MethodHandler> result = new LinkedHashMap<String, MethodHandler>();
  //便利元数据信息
  for (MethodMetadata md : metadata) {
    BuildTemplateByResolvingArgs buildTemplate;
    //从参数构建表单编码模板
    if (!md.formParams().isEmpty() && md.template().bodyTemplate() == null) {
      buildTemplate = new BuildFormEncodedTemplateFromArgs(md, encoder, queryMapEncoder);
    } 
    //从参数构建编码模板
    else if (md.bodyIndex() != null) {
      buildTemplate = new BuildEncodedTemplateFromArgs(md, encoder, queryMapEncoder);
    } 
    //通过解析参数来构建模板
    else {
      buildTemplate = new BuildTemplateByResolvingArgs(md, queryMapEncoder);
    }
    //添加到map中 value为 SynchronousMethodHandler 线程安全的 MethodHandler
    result.put(md.configKey(),
        factory.create(key, md, buildTemplate, options, decoder, errorDecoder));
  }
  return result;
}

SpringMvcContract实现了 Abstract BaseContract 类型

@Override
public List<MethodMetadata> parseAndValidatateMetadata(Class<?> targetType) {
  // 它返回一个TypeVariable数组,该数组表示由泛型声明定义的变量类型。
   //当基础泛型声明未定义任何变量类型时,它将返回 0
  checkState(targetType.getTypeParameters().length == 0,"Parameterized types unsupported: %s", targetType.getSimpleName());
      //只支持单级继承
  checkState(targetType.getInterfaces().length <= 1,"Only single inheritance supported: %s",targetType.getSimpleName());
      //只支持单级继承
  if (targetType.getInterfaces().length == 1) {
    checkState(targetType.getInterfaces()[0].getInterfaces().length == 0,"Only single-level inheritance supported: %s",targetType.getSimpleName());
  }
  //创建map存储
  Map<String, MethodMetadata> result = new LinkedHashMap<String, MethodMetadata>();
  for (Method method : targetType.getMethods()) {
      //判断此方法不是obejct类的方法 hashCode() equals() clone() 方法等
    if (method.getDeclaringClass() == Object.class ||
    //判断不是一个静态方法
(method.getModifiers() & Modifier.STATIC) != 0 ||
    //判断不是默认方法
        Util.isDefault(method)) {
      continue;
    }
    //解析方法元数据信息 子类重写了夫类 具体看子类SpringMvcContract中实现
    MethodMetadata metadata = parseAndValidateMetadata(targetType, method);
    //判断result是否有@Override 注解
    checkState(!result.containsKey(metadata.configKey()), "Overrides unsupported: %s",
        metadata.configKey());
        //添加到map中
    result.put(metadata.configKey(), metadata);
  }
  return new ArrayList<>(result.values());
}

SpringMvcContract类中 parseAndValidateMetadata方法

@Override
public MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
    //已经处理的方法放入到map中 key生成策略类#方法名(参数) DingTalkFeign#send(DingWebhookDTO,String)
   this.processedMethods.put(Feign.configKey(targetType, method), method);
   //使用父类(BaseContract)解析获取方法元数据信息
   MethodMetadata md = super.parseAndValidateMetadata(targetType, method);
    //获取类上的@RequestMapping注解
   RequestMapping classAnnotation = findMergedAnnotation(targetType,
         RequestMapping.class);
         //设置类上面@RequestMapping注解 只有当方法上面没有指定属性时 类上面指定的属性才生效
   if (classAnnotation != null) {
      // acceept请求头配置
      if (!md.template().headers().containsKey(ACCEPT)) {
         parseProduces(md, method, classAnnotation);
      }
      //content-type请求头配置
      if (!md.template().headers().containsKey(CONTENT_TYPE)) {
         parseConsumes(md, method, classAnnotation);
      }
      //类的注解是从方法那里拿过来的 如果有的话,一定要写这些
      parseHeaders(md, method, classAnnotation);
   }
   return md;
}

BaseContract中parseAndValidateMetadata方法

protected MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
    //创建MethodMetadata对象
  MethodMetadata data = new MethodMetadata();
  //解析并设置返回值类型 里面解析逻辑比较复杂 涉及到递归解析
  data.returnType(Types.resolve(targetType, targetType, method.getGenericReturnType()));
  //生成并设置configKey 
  data.configKey(Feign.configKey(targetType, method));
 //使用子类SpringMvcContract处理类上面加@RequestMapper的uri 并设置template的uri信息
  if (targetType.getInterfaces().length == 1) {
    processAnnotationOnClass(data, targetType.getInterfaces()[0]);
  }
  processAnnotationOnClass(data, targetType);

//解析每个方法上的@ReuqestMapping注解包括对方法返回值,请求uri以及请求头和参数@Param注解的处理
  for (Annotation methodAnnotation : method.getAnnotations()) {
    processAnnotationOnMethod(data, methodAnnotation, method);
  }
  //检测方法的http method不能为空
  checkState(data.template().method() != null,
      "Method %s not annotated with HTTP method type (ex. GET, POST)",
      method.getName());
      //获取参数类类型
  Class<?>[] parameterTypes = method.getParameterTypes();
  //获取参数的范型类型
  Type[] genericParameterTypes = method.getGenericParameterTypes();
    //获取参数注解二维数组
  Annotation[][] parameterAnnotations = method.getParameterAnnotations();
  //获取长度
  int count = parameterAnnotations.length;
  //遍历
  for (int i = 0; i < count; i++) {
    boolean isHttpAnnotation = false;
    if (parameterAnnotations[i] != null) {
        //判断参数是否包含1、PathVariable 2、RequestParam 3、RequestHeader 4、SpringQueryMap 这个4个注解
        //使用相应的处理器处理完成之后 设置到RequestTemplate中
      isHttpAnnotation = processAnnotationsOnParameter(data, parameterAnnotations[i], i);
    }
    //判断是否为uri类型
    if (parameterTypes[i] == URI.class) {
      data.urlIndex(i);
    } 
    //如果非上面4个注解,并且参数类型不是options类型 
    else if (!isHttpAnnotation && parameterTypes[i] != Request.Options.class) {
        //主体参数不能与表单参数一起使用(body和表单不能同时使用)
      checkState(data.formParams().isEmpty(),
          "Body parameters cannot be used with form parameters.");
          //方法有太多的Body参数
      checkState(data.bodyIndex() == null, "Method has too many Body parameters: %s", method);
      //设置body请求体下标
      data.bodyIndex(i);
      //解析body类型 根返回值解析一个方法 比较复杂包含了 递归
      data.bodyType(Types.resolve(targetType, targetType, genericParameterTypes[i]));
    }
  }
    //如果headerMapIndex不为空
  if (data.headerMapIndex() != null) {
      //校验参数类型必须为map 检查key必须为String类型 直接传入HeaderMap固定值
    checkMapString("HeaderMap", parameterTypes[data.headerMapIndex()],
        genericParameterTypes[data.headerMapIndex()]);
  }
    //查询的queryMap校验 和上面一样的规则
  if (data.queryMapIndex() != null) {
    if (Map.class.isAssignableFrom(parameterTypes[data.queryMapIndex()])) {
      checkMapKeys("QueryMap", genericParameterTypes[data.queryMapIndex()]);
    }
  }
    //返回方法元数据信息
  return data;
}

SpringMvcContract中processAnnotationOnClass方法

@Override
protected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {
   if (clz.getInterfaces().length == 0) {
       //获取类上面的@RequestMapping注解添加到 MethodMetadata.RequestTemplate.uri中
      RequestMapping classAnnotation = findMergedAnnotation(clz,
            RequestMapping.class);
      if (classAnnotation != null) {
         // 如果指定,则从类注释中预先添加路径
         if (classAnnotation.value().length > 0) {
            String pathValue = emptyToNull(classAnnotation.value()[0]);
            //占位符处理
            pathValue = resolve(pathValue);
            //非/开头 添加/
            if (!pathValue.startsWith("/")) {
               pathValue = "/" + pathValue;
            }
            data.template().uri(pathValue);
         }
      }
   }
}

SpringMvcContract中processAnnotationOnMethod方法

@Override
protected void processAnnotationOnMethod(MethodMetadata data,
      Annotation methodAnnotation, Method method) {
          //判断方法的注解上必须有@RequestMapping
   if (!RequestMapping.class.isInstance(methodAnnotation) && !methodAnnotation
         .annotationType().isAnnotationPresent(RequestMapping.class)) {
      return;
   }
    //获取@RequestMapping注解
   RequestMapping methodMapping = findMergedAnnotation(method, RequestMapping.class);
   // 获取HTTP Method 如果没有定义默认为RequestMethod.GET 
   RequestMethod[] methods = methodMapping.method();
   if (methods.length == 0) {
      methods = new RequestMethod[] { RequestMethod.GET };
   }
   //检查@RequestMapping注解中只能有一个 http method
   checkOne(method, methods, "method");
   //设置元方法数据的请求 RequestTamplate属性的method
   data.template().method(Request.HttpMethod.valueOf(methods[0].name()));
   //检查@RequestMapping value 属性 values != null && (values.length == 0 || values.length == 1)
   checkAtMostOne(method, methodMapping.value(), "value");
     //如果@ReuqestMapping中的value值不为空 进行url解析 追加 到data中的RequestTemplate属性的uri
   if (methodMapping.value().length > 0) {
      String pathValue = emptyToNull(methodMapping.value()[0]);
      if (pathValue != null) {
          //占位符处理
         pathValue = resolve(pathValue);
        //如果不是以"/"开头 添加"/"
         if (!pathValue.startsWith("/") && !data.template().path().endsWith("/")) {
            pathValue = "/" + pathValue;
         }
         data.template().uri(pathValue, true);
      }
   }
   //解析@RequestMapping  中produces属性 进行 data中ReqeustTemplate的header中的accept设置 
   //md.template().header(ACCEPT, clientAccepts);
   parseProduces(data, method, methodMapping);
   //解析@RequestMapping  中consumes属性 进行 data中ReqeustTemplate的header设置中的content-type设置 
   parseConsumes(data, method, methodMapping);
   //解析@RequestMapping  中headers属性 对"name=value" 进行处理并添加到 headers中 里面包含了占位符处理逻辑
   parseHeaders(data, method, methodMapping);
   //参数处理将@Param注解和参数的下标绑定起来
   data.indexToExpander(new LinkedHashMap<Integer, Param.Expander>());
}

SpringMvcContract中processAnnotationsOnParameter方法

@Override
protected boolean processAnnotationsOnParameter(MethodMetadata data,
      Annotation[] annotations, int paramIndex) {
          //是否为http注解
   boolean isHttpAnnotation = false;
   //定义注解参数处理器
   AnnotatedParameterProcessor.AnnotatedParameterContext context = new SimpleAnnotatedParameterContext(
         data, paramIndex);
         //从缓存中根据 configKey获取method
   Method method = this.processedMethods.get(data.configKey());
   //遍历处理注解
   for (Annotation parameterAnnotation : annotations) {
       //annotatedArgumentProcessors的数据类型Map<Class<? extends Annotation>, AnnotatedParameterProcessor>
       //key为注解,value为处理类,总共有4个注解和处理类 
       //1、PathVariable 2、RequestParam 3、RequestHeader 4、SpringQueryMap
      AnnotatedParameterProcessor processor = this.annotatedArgumentProcessors
            .get(parameterAnnotation.annotationType());
        //获取到处理类不为空
      if (processor != null) {
         Annotation processParameterAnnotation;
         // synthesize, handling @AliasFor, while falling back to parameter name on missing String #value():
         processParameterAnnotation = synthesizeWithMethodParameterNameAsFallbackValue(
               parameterAnnotation, method, paramIndex);
               //处理注解参数
         isHttpAnnotation |= processor.processArgument(context,
               processParameterAnnotation, method);
      }
   }
    //如果是http注解并且下标取值不为空
   if (isHttpAnnotation && data.indexToExpander().get(paramIndex) == null) {
       //创建参数类型 里面包括了对Iterable类型的处理
      TypeDescriptor typeDescriptor = createTypeDescriptor(method, paramIndex);
      //判断参数类型是否可以转换成String类型
      if (this.conversionService.canConvert(typeDescriptor,
            STRING_TYPE_DESCRIPTOR)) {
         Param.Expander expander = this.convertingExpanderFactory
               .getExpander(typeDescriptor);
         if (expander != null) {
             //将expander(一个lambda表达式) 放入到data中 
            data.indexToExpander().put(paramIndex, expander);
         }
      }
   }
   return isHttpAnnotation;
}
  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值