Feign.builder().target()都做了什么操作!

Scroll Down

Feign的执行流程

Weather weather = Feign.builder()
                    .client(new Client.Default(null,null))
                    .decoder(new Decoder.Default())
                    .encoder(new Encoder.Default())
                    .target(Weather.class, "http://t.weather.sojson.com/api/weather/city/101030100");

从上面可以看到Feign做完build之后通过调用target()方法直接就返回了我们想要的结果,接下来一点点探索各个方法都做了什么。

builder()

public static class Builder {
    // 请求拦截器
    private final List<RequestInterceptor> requestInterceptors =
        new ArrayList<RequestInterceptor>();
    // 日志级别
    private Logger.Level logLevel = Logger.Level.NONE;
    // 凭证信息
    private Contract contract = new Contract.Default();
    // 请求client
    private Client client = new Client.Default(null, null);
    // 重试器
    private Retryer retryer = new Retryer.Default();
    // 日志打印器
    private Logger logger = new NoOpLogger();
    // 编码器
    private Encoder encoder = new Encoder.Default();
    // 解码器
    private Decoder decoder = new Decoder.Default();
    // QueryMap编码器
    private QueryMapEncoder queryMapEncoder = new FieldQueryMapEncoder();
    // 错误解码器
    private ErrorDecoder errorDecoder = new ErrorDecoder.Default();
    // 请求参数(超时、连接时间等配置)
    private Options options = new Options();
    // 代理工厂
    private InvocationHandlerFactory invocationHandlerFactory =
        new InvocationHandlerFactory.Default();
    // 404是否处理
    private boolean decode404;
    // 解码后关闭连接
    private boolean closeAfterDecode = true;
    private ExceptionPropagationPolicy propagationPolicy = NONE;
    // 强制转换编码
    private boolean forceDecoding = false;
    // 增强解析器
    private List<Capability> capabilities = new ArrayList<>();
}

从上文中可以看到在builder中包含了基本上feign的所有核心的内容。

target()

public <T> T target(Class<T> apiType, String url) {
  // 创建硬编码Target对象
  return target(new HardCodedTarget<T>(apiType, url));
}

public <T> T target(Target<T> target) {
  // 构造并创建实例对象
  return build().newInstance(target);
}

public interface Target<T> {
  // 返回对象类型
  Class<T> type();
  // key名称
  String name();
  // 请求地址
  String url();
  // 构建Request
  public Request apply(RequestTemplate input);
}

上文中可以看到最终创建了一个HardCodedTarget,实现了Target接口。接下来看下build方法和newInstance方法都做了什么操作。

build()

public Feign build() {
      // 请求Client信息,默认HttpURLConnection
      Client client = Capability.enrich(this.client, capabilities);
      // 重试机制默认请求间隔100毫秒,最大重试间隔1秒,最多重试5次
      Retryer retryer = Capability.enrich(this.retryer, capabilities);
      // 请求拦截器
      List<RequestInterceptor> requestInterceptors = this.requestInterceptors.stream()
          .map(ri -> Capability.enrich(ri, capabilities))
          .collect(Collectors.toList());
      // 日志处理器
      Logger logger = Capability.enrich(this.logger, capabilities);
      // 契约信息,也就是定义了@Headers、@RequestLine、@Body、@Param等注解的处理器
      Contract contract = Capability.enrich(this.contract, capabilities);
      // 选项信息,配置Http请求的连接超时时间,读取超时时间
      Options options = Capability.enrich(this.options, capabilities);
      // 编码器
      Encoder encoder = Capability.enrich(this.encoder, capabilities);
      // 解码器
      Decoder decoder = Capability.enrich(this.decoder, capabilities);
      // 代理处理工厂
      InvocationHandlerFactory invocationHandlerFactory =
          Capability.enrich(this.invocationHandlerFactory, capabilities);
      // 查询Encoder
      QueryMapEncoder queryMapEncoder = Capability.enrich(this.queryMapEncoder, capabilities);
      // 同步方法是处理器
      SynchronousMethodHandler.Factory synchronousMethodHandlerFactory =
          new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors, logger,
              logLevel, decode404, closeAfterDecode, propagationPolicy, forceDecoding);
      // 根据名称转换
      ParseHandlersByName handlersByName =
          new ParseHandlersByName(contract, options, encoder, decoder, queryMapEncoder,
              errorDecoder, synchronousMethodHandlerFactory);
      return new ReflectiveFeign(handlersByName, invocationHandlerFactory, queryMapEncoder);
}

build后,从Capability中再次解析,构建了代理处理工厂和同步处理器。最后创建了一个ReflectiveFeign实例对象。创建实例的时候传入了handlersByNameinvocationHandlerFactoryqueryMapEncoder三个参数。

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()) {
      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;
}

接下来看下Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);处理器的获取方案是如何获取的。然后在看下工厂处理方法。

targetToHandlersByName.apply

public Map<String, MethodHandler> apply(Target target) {
      // 转换并且验证生成当前target的metadata
      List<MethodMetadata> metadata = contract.parseAndValidateMetadata(target.type());
      Map<String, MethodHandler> result = new LinkedHashMap<String, MethodHandler>();
      // 循环metadata
      for (MethodMetadata md : metadata) {
        BuildTemplateByResolvingArgs buildTemplate;
        if (!md.formParams().isEmpty() && md.template().bodyTemplate() == null) {
          // 构建模板信息
          buildTemplate =
              new BuildFormEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
        } else if (md.bodyIndex() != null) {
          // 构建模板信息
          buildTemplate = new BuildEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
        } else {
          // 构建模板信息
          buildTemplate = new BuildTemplateByResolvingArgs(md, queryMapEncoder, target);
        }
        if (md.isIgnored()) {
          result.put(md.configKey(), args -> {
            throw new IllegalStateException(md.configKey() + " is not a method handled by feign");
          });
        } else {
          result.put(md.configKey(),
              // 创建代理信息
              factory.create(target, md, buildTemplate, options, decoder, errorDecoder));
        }
      }
      return result;
}

public MethodHandler create(Target<?> target,
                                MethodMetadata md,
                                RequestTemplate.Factory buildTemplateFromArgs,
                                Options options,
                                Decoder decoder,
                                ErrorDecoder errorDecoder) {
  return new SynchronousMethodHandler(target, client, retryer, requestInterceptors, logger,
      logLevel, md, buildTemplateFromArgs, options, decoder,
      errorDecoder, decode404, closeAfterDecode, propagationPolicy, forceDecoding);
}

最终可以看到创建了key和SynchronousMethodHandler的实例关系的map进行返回。

factory.create

// 创建代理处理器
InvocationHandler handler = factory.create(target, methodToHandler);
// 创建代理实例对象
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),
    new Class<?>[] {target.type()}, handler);

// 默认动态代理处理工程
static final class Default implements InvocationHandlerFactory {

    @Override
    public InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch) {
      // 反射处理代理处理器
      return new ReflectiveFeign.FeignInvocationHandler(target, dispatch);
    }
}