Fegin的执行流程

Scroll Down

Fegin.Builder

// 请求拦截器
private final List<RequestInterceptor> requestInterceptors =
        new ArrayList<RequestInterceptor>();
// 日志级别        
private Logger.Level logLevel = Logger.Level.NONE;
// 请求的契约信息
private Contract contract = new Contract.Default();
// 客户端
private Client client = new Client.Default(null, null);
// 重试器
private Retryer retryer = new Retryer.Default();
// 日志
private Logger logger = new NoOpLogger();
// encoder
private Encoder encoder = new Encoder.Default();
// decoder
private Decoder decoder = new Decoder.Default();
// 查询map encoder
private QueryMapEncoder queryMapEncoder = new QueryMapEncoder.Default();
// 错误encoder
private ErrorDecoder errorDecoder = new ErrorDecoder.Default();
// 配置参数信息
private Options options = new Options();
// 反射工厂
private InvocationHandlerFactory invocationHandlerFactory =
    new InvocationHandlerFactory.Default();
// 404decoder是否启用
private boolean decode404;
// decode后关闭
private boolean closeAfterDecode = true;
// 传播方式
private ExceptionPropagationPolicy propagationPolicy = NONE;

从上面的Builder内部类中我们可以看到配置了拦截器、重试器、客户端、encoder、decoder、参数配置等信息。

target方法

public <T> T target(Class<T> apiType, String url) {
  return target(new HardCodedTarget<T>(apiType, url));
}

public <T> T target(Target<T> target) {
  return build().newInstance(target);
}

build方法

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);
  // 创建ReflectiveFeign子类
  return new ReflectiveFeign(handlersByName, invocationHandlerFactory, queryMapEncoder);
}

在build方法中可以看到直接返回了Feign信息。下面需要看下newInstance方法。

public abstract <T> T newInstance(Target<T> target);

newInstance方法是Feign抽象类中的一个抽象方法,上文中我们也看到了直接创建的是ReflectiveFeign子类,所以我们直接看子类中的newInstance方法。

public <T> T newInstance(Target<T> target) {
    // 构建元数据
    Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);
    // 方法处理器
    Map<Method, MethodHandler> methodToHandler = new LinkedHashMap<Method, MethodHandler>();
    // 默认方法处理器
    List<DefaultMethodHandler> defaultMethodHandlers = new LinkedList<DefaultMethodHandler>();

    // 循环方法
    for (Method method : target.type().getMethods()) {
      // 判断返回类型是否是Object
      if (method.getDeclaringClass() == Object.class) {
        continue;
      // 工具类判断是否是默认方法
      } else if (Util.isDefault(method)) {
        DefaultMethodHandler handler = new DefaultMethodHandler(method);
        defaultMethodHandlers.add(handler);
        methodToHandler.put(method, handler);
      // 构建方法处理器
      } else {
        methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));
      }
    }
    // 工厂创建方法处理器
    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;
}

apply方法

public Map<String, MethodHandler> apply(Target key) {
  // 转换并验证元数据信息
  List<MethodMetadata> metadata = contract.parseAndValidatateMetadata(key.type());
  // 方法处理器集合
  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);
    }
    // 方法处理器
    result.put(md.configKey(),
        factory.create(key, md, buildTemplate, options, decoder, errorDecoder));
  }
  return result;
}

上文中的contract是通过Contract.Default()创建出来的看下Default中的parseAndValidatateMetadata方法。

public List<MethodMetadata> parseAndValidatateMetadata(Class<?> targetType) {
  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<String, MethodMetadata> result = new LinkedHashMap<String, MethodMetadata>();
  // 循环当前方法
  for (Method method : targetType.getMethods()) {
    if (method.getDeclaringClass() == Object.class ||
        (method.getModifiers() & Modifier.STATIC) != 0 ||
        Util.isDefault(method)) {
      continue;
    }
    // 转换并验证元数据信息
    MethodMetadata metadata = parseAndValidateMetadata(targetType, method);
    checkState(!result.containsKey(metadata.configKey()), "Overrides unsupported: %s",
        metadata.configKey());
    // 设置元数据集合
    result.put(metadata.configKey(), metadata);
  }
  return new ArrayList<>(result.values());
}

parseAndValidateMetadata方法

protected MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
  // 创建元数据信息
  MethodMetadata data = new MethodMetadata();
  // 设置返回值类型
  data.returnType(Types.resolve(targetType, targetType, method.getGenericReturnType()));
  // 设置configkey的值“classname#method(param,param)”
  data.configKey(Feign.configKey(targetType, method));
  // 判断注解数据
  if (targetType.getInterfaces().length == 1) {
    processAnnotationOnClass(data, targetType.getInterfaces()[0]);
  }
  // 处理注解
  processAnnotationOnClass(data, targetType);

  // 循环注解处理
  for (Annotation methodAnnotation : method.getAnnotations()) {
    processAnnotationOnMethod(data, methodAnnotation, 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) {
      isHttpAnnotation = processAnnotationsOnParameter(data, parameterAnnotations[i], i);
    }
    if (parameterTypes[i] == URI.class) {
      data.urlIndex(i);
    } else if (!isHttpAnnotation) {
      checkState(data.formParams().isEmpty(),
          "Body parameters cannot be used with form parameters.");
      checkState(data.bodyIndex() == null, "Method has too many Body parameters: %s", method);
      data.bodyIndex(i);
      data.bodyType(Types.resolve(targetType, targetType, genericParameterTypes[i]));
    }
  }

  if (data.headerMapIndex() != null) {
    checkMapString("HeaderMap", parameterTypes[data.headerMapIndex()],
        genericParameterTypes[data.headerMapIndex()]);
  }

  if (data.queryMapIndex() != null) {
    if (Map.class.isAssignableFrom(parameterTypes[data.queryMapIndex()])) {
      checkMapKeys("QueryMap", genericParameterTypes[data.queryMapIndex()]);
    }
  }

  return data;
}

processAnnotationOnClass

static final Pattern REQUEST_LINE_PATTERN = Pattern.compile("^([A-Z]+)[ ]*(.*)$");

@Override
protected void processAnnotationOnClass(MethodMetadata data, Class<?> targetType) {
  // 判断类头上是否有Headers注解
  if (targetType.isAnnotationPresent(Headers.class)) {
    String[] headersOnType = targetType.getAnnotation(Headers.class).value();
    checkState(headersOnType.length > 0, "Headers annotation was empty on type %s.",
        targetType.getName());
    Map<String, Collection<String>> headers = toMap(headersOnType);
    headers.putAll(data.template().headers());
    data.template().headers(null); // to clear
    // 设置头信息
    data.template().headers(headers);
  }
}
// 处理map
private static Map<String, Collection<String>> toMap(String[] input) {
  Map<String, Collection<String>> result =
      new LinkedHashMap<String, Collection<String>>(input.length);
  for (String header : input) {
    int colon = header.indexOf(':');
    String name = header.substring(0, colon);
    if (!result.containsKey(name)) {
      result.put(name, new ArrayList<String>(1));
    }
    result.get(name).add(header.substring(colon + 1).trim());
  }
  return result;
}

processAnnotationOnMethod

protected void processAnnotationOnMethod(MethodMetadata data,
                                         Annotation methodAnnotation,
                                         Method method) {
  // 获取注解类型
  Class<? extends Annotation> annotationType = methodAnnotation.annotationType();
  // 判断方法上注解是否是RequestLine
  if (annotationType == RequestLine.class) {
    // 获取value
    String requestLine = RequestLine.class.cast(methodAnnotation).value();
    checkState(emptyToNull(requestLine) != null,
        "RequestLine annotation was empty on method %s.", method.getName());
    // 正则匹配RequestLine
    Matcher requestLineMatcher = REQUEST_LINE_PATTERN.matcher(requestLine);
    if (!requestLineMatcher.find()) {
      throw new IllegalStateException(String.format(
          "RequestLine annotation didn't start with an HTTP verb on method %s",
          method.getName()));
    } else {
      // 设置请求方式
      data.template().method(HttpMethod.valueOf(requestLineMatcher.group(1)));
      // 设置请求地址
      data.template().uri(requestLineMatcher.group(2));
    }
    // 是否解码
    data.template().decodeSlash(RequestLine.class.cast(methodAnnotation).decodeSlash());
    // 集合转换
    data.template()
        .collectionFormat(RequestLine.class.cast(methodAnnotation).collectionFormat());
  // 判断注解类型是否是Body
  } else if (annotationType == Body.class) {
    // 设置body
    String body = Body.class.cast(methodAnnotation).value();
    checkState(emptyToNull(body) != null, "Body annotation was empty on method %s.",
        method.getName());
    // 设置body或者bodyTemplate
    if (body.indexOf('{') == -1) {
      data.template().body(body);
    } else {
      data.template().bodyTemplate(body);
    }
  // 判断注解类型是否是Header
  } else if (annotationType == Headers.class) {
    String[] headersOnMethod = Headers.class.cast(methodAnnotation).value();
    checkState(headersOnMethod.length > 0, "Headers annotation was empty on method %s.",
        method.getName());
    // 设置header
    data.template().headers(toMap(headersOnMethod));
  }
}

动态代理invoke

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  if ("equals".equals(method.getName())) {
    try {
      Object otherHandler =
          args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
      return equals(otherHandler);
    } catch (IllegalArgumentException e) {
      return false;
    }
  } else if ("hashCode".equals(method.getName())) {
    return hashCode();
  } else if ("toString".equals(method.getName())) {
    return toString();
  }
  // 获取执行器,进行invoke
  return dispatch.get(method).invoke(args);
}

invoke

public Object invoke(Object[] argv) throws Throwable {
    // 创建请求模板
    RequestTemplate template = buildTemplateFromArgs.create(argv);
    // 设置重试器
    Retryer retryer = this.retryer.clone();
    // 循环执行
    while (true) {
      try {
        return executeAndDecode(template);
      } catch (RetryableException e) {
        try {
          retryer.continueOrPropagate(e);
        } catch (RetryableException th) {
          Throwable cause = th.getCause();
          if (propagationPolicy == UNWRAP && cause != null) {
            throw cause;
          } else {
            throw th;
          }
        }
        if (logLevel != Logger.Level.NONE) {
          logger.logRetry(metadata.configKey(), logLevel);
        }
        continue;
      }
    }
}

create

public RequestTemplate create(Object[] argv) {
  // 构造请求模板
  RequestTemplate mutable = RequestTemplate.from(metadata.template());
  // 判断连接信息
  if (metadata.urlIndex() != null) {
    int urlIndex = metadata.urlIndex();
    checkArgument(argv[urlIndex] != null, "URI parameter %s was null", urlIndex);
    mutable.target(String.valueOf(argv[urlIndex]));
  }
  // 定义请求参数
  Map<String, Object> varBuilder = new LinkedHashMap<String, Object>();
  // 循环获取请求参数
  for (Entry<Integer, Collection<String>> entry : metadata.indexToName().entrySet()) {
    int i = entry.getKey();
    Object value = argv[entry.getKey()];
    if (value != null) { // Null values are skipped.
      if (indexToExpander.containsKey(i)) {
        value = expandElements(indexToExpander.get(i), value);
      }
      for (String name : entry.getValue()) {
        varBuilder.put(name, value);
      }
    }
  }
  // 设置请求参数
  RequestTemplate template = resolve(argv, mutable, varBuilder);
  // 判断请求参数位置是否为空,设置请求参数
  if (metadata.queryMapIndex() != null) {
    // add query map parameters after initial resolve so that they take
    // precedence over any predefined values
    Object value = argv[metadata.queryMapIndex()];
    Map<String, Object> queryMap = toQueryMap(value);
    template = addQueryMapQueryParameters(queryMap, template);
  }

  if (metadata.headerMapIndex() != null) {
    template =
        addHeaderMapHeaders((Map<String, Object>) argv[metadata.headerMapIndex()], template);
  }
  // 返回请求模板
  return template;
}

executeAndDecode

Object executeAndDecode(RequestTemplate template) throws Throwable {
    // 构建request信息
    Request request = targetRequest(template);

    if (logLevel != Logger.Level.NONE) {
      logger.logRequest(metadata.configKey(), logLevel, request);
    }
    // 响应信息
    Response response;
    // 请求开始时间
    long start = System.nanoTime();
    try {
      // 调用client执行,这里面也就是new Client.Default(null, null);
      response = client.execute(request, options);
    } catch (IOException e) {
      if (logLevel != Logger.Level.NONE) {
        logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime(start));
      }
      // 请求异常抛出
      throw errorExecuting(request, e);
    }
    // 执行时间
    long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);

    boolean shouldClose = true;
    try {
      if (logLevel != Logger.Level.NONE) {
        response =
            logger.logAndRebufferResponse(metadata.configKey(), logLevel, response, elapsedTime);
      }
      // 判断返回类型是否是Response
      if (Response.class == metadata.returnType()) {
        if (response.body() == null) {
          return response;
        }
        if (response.body().length() == null ||
            response.body().length() > MAX_RESPONSE_BUFFER_SIZE) {
          shouldClose = false;
          return response;
        }
        // 构建body数据
        // Ensure the response body is disconnected
        byte[] bodyData = Util.toByteArray(response.body().asInputStream());
        return response.toBuilder().body(bodyData).build();
      }
      // 判断响应码是否是在200和300之间
      if (response.status() >= 200 && response.status() < 300) {
        // 如果返回类型是void,直接rerurn null;
        if (void.class == metadata.returnType()) {
          return null;
        } else {
          // decode进行解码
          Object result = decode(response);
          shouldClose = closeAfterDecode;
          return result;
        }
      // 判断404处理
      } else if (decode404 && response.status() == 404 && void.class != metadata.returnType()) {
        Object result = decode(response);
        shouldClose = closeAfterDecode;
        return result;
      } else {
        throw errorDecoder.decode(metadata.configKey(), response);
      }
    } catch (IOException e) {
      if (logLevel != Logger.Level.NONE) {
        logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime);
      }
      // 判断异常
      throw errorReading(request, response, e);
    } finally {
      if (shouldClose) {
        // 处理结果
        ensureClosed(response.body());
      }
    }
}

decode

Object decode(Response response) throws Throwable {
    try {
      // 返回decode信息
      return decoder.decode(response, metadata.returnType());
    } catch (FeignException e) {
      throw e;
    } catch (RuntimeException e) {
      throw new DecodeException(response.status(), e.getMessage(), e);
    }
}