Feign的动态代理

Scroll Down

FeignInvocationHandler

FeignInvocationHandler实现了InvocationHandler,最终代理会调用invoke方法

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  // 排除equals,hashCode,toString方法
  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又通过dispatch.get(method).invoke(args)来进行执行。而dispatch.get(method)返回的正是SynchronousMethodHandler

SynchronousMethodHandler.invoke()

public Object invoke(Object[] argv) throws Throwable {
    // 构建请求模板
    RequestTemplate template = buildTemplateFromArgs.create(argv);
    // 查询当前选配信息
    Options options = findOptions(argv);
    // 获取重试起
    Retryer retryer = this.retryer.clone();
    while (true) {
      try {
        // 执行并且decode
        return executeAndDecode(template, options);
      } 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;
      }
    }
}

SynchronousMethodHandler.invoke()方法中可以明确看出执行了最终的请求信息,也包含了重试的一些逻辑信息。

executeAndDecode()

Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
    // 根据模板构建请求
    Request request = targetRequest(template);
    // 记录请求日志
    if (logLevel != Logger.Level.NONE) {
      logger.logRequest(metadata.configKey(), logLevel, request);
    }
    // 定义响应结果
    Response response;
    // 定义当前时间
    long start = System.nanoTime();
    try {
      // 执行请求,默认的会调用Client.Default()的client信息
      response = client.execute(request, options);
      // ensure the request is set. TODO: remove in Feign 12
      response = response.toBuilder()
          .request(request)
          .requestTemplate(template)
          .build();
    } 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);

    // 判断解码器是否为空
    if (decoder != null)
      // 解码器不为空返回解码数据
      return decoder.decode(response, metadata.returnType());

    // 异步处理
    CompletableFuture<Object> resultFuture = new CompletableFuture<>();
    // 异步响应
    asyncResponseHandler.handleResponse(resultFuture, metadata.configKey(), response,
        metadata.returnType(),
        elapsedTime);

    try {
      if (!resultFuture.isDone())
        throw new IllegalStateException("Response handling not done");

      return resultFuture.join();
    } catch (CompletionException e) {
      Throwable cause = e.getCause();
      if (cause != null)
        throw cause;
      throw e;
    }
}

response = client.execute(request, options);这句话也就是最终真正发起的请求。return decoder.decode(response, metadata.returnType())decoder来进行解码操作。