feign分析第三篇

270 阅读3分钟

「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。

MethodHandler

方法执行器, 类似于: InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])

Object invoke(Object[] argv) throws Throwable;

02MethodHandler1.jpg

DefaultMethodHandler : 适配了JDK中的MethodHandle, 使用MethodHandle进行方法的调用和绑定

SynchronousMethodHandler:同步方法调用,具备自己的内部工厂SynchronousMethodHandler.Factory,用于方便创建。 核心代码如下:

 @Override
  public Object invoke(Object[] argv) throws Throwable {
    // 创建请求模版
    RequestTemplate template = buildTemplateFromArgs.create(argv);
    // 查找配置
    Options options = findOptions(argv);
    // 重试策略克隆
    Retryer retryer = this.retryer.clone();
    while (true) {
      try {
        // 执行调用并解码
        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) {
          // 日志级别不为none , 打印重试日志
          logger.logRetry(metadata.configKey(), logLevel);
        }
        continue;
      }
    }
  }

InvocationHandlerFactory

用于创建JDK中InvocationHandler的工厂接口。

02InvocationHandlerFactory1.jpg

InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch);` 根据target,和方法路由, 创建出`InvocationHandler

具体创建的产品InvocationHandler查看下图:

02InvocationHandlerFactory2.jpg

其中设计到的设计模式有: 工厂方法, 模版方法, 装饰器

工厂方法

  1. 抽象工厂角色 InvocationHandlerFactory
  2. 抽象产品角色InvocationHandler
  3. 具体工厂MeteredInvocationHandleFactory,Default,ReactorFeign.ReactorInvocationHandlerFactory,RxJavaFeign.ReactorInvocationHandlerFactory
  4. 具体产品: 匿名lambdaReflectiveFeign.FeignInvocationHandlerReactorInvocationHandlerRxJavaInvocationHandler
  5. 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
  6. 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
  7. 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足开闭原则、迪米特法则、依赖倒置原则和里氏替换原则。

模版方法

  1. 抽象类: ReactiveInvocationHandler
  2. 具体实现子类: ReactorInvocationHandler,RxJavaInvocationHandler
  3. 模版方法:public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {....}
  4. 抽象方法: protected abstract Publisher invoke(Method method, MethodHandler methodHandler,Object[] arguments);
  5. 在父类中提取了公共的部分代码,便于代码复用。

装饰器

  1. 抽象构件: InvocationHandlerFactory
  2. 具体构件: DefaultReactorFeign.ReactorInvocationHandlerFactoryRxJavaFeign.ReactorInvocationHandlerFactory
  3. 具体装饰: MeteredInvocationHandleFactory 在原有的factory生产的产品上 增加了监控功能

Feign

Feign的目的是简化对假装休息的http api的开发, 在实现中,Feign是一个{@link Feign#newInstance工厂}用于生成{@link Target targeted} HTTP api。

程序入口

Feign.builder().build().target(Target target);

02feign1.jpg 同步实现: ReflectiveFeign

异步实现: AsyncFeign 还不完善

Feign.Builder主要是生产 ReflectiveFeign,核心代码:

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

    public Feign build() {
      Client client = Capability.enrich(this.client, capabilities);
      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);
      Contract contract = Capability.enrich(this.contract, capabilities);
      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);
      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);
    }
  }

ReflectiveFeign, 核心代码:

// 创建target泛型中的对象
@Override
  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);
    // 生成代理对象, 绑定handler
    T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),
        new Class<?>[] {target.type()}, handler);
	 // 代理对象上绑定默认的 方法处理
    for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
      defaultMethodHandler.bindTo(proxy);
    }
    return proxy;
  }

02feign2.jpg

ParseHandlersByName**

根据名称解析handler

02ParseHandlersByName1.jpg

核心代码

public Map<String, MethodHandler> apply(Target target) {
   // 约束解析出方法的元数据
    List<MethodMetadata> metadata = contract.parseAndValidateMetadata(target.type());
    Map<String, MethodHandler> result = new LinkedHashMap<String, MethodHandler>();
    for (MethodMetadata md : metadata) {
      BuildTemplateByResolvingArgs buildTemplate;
      if (!md.formParams().isEmpty() && md.template().bodyTemplate() == null) {
        // BuildFormEncodedTemplateFromArgs 是RequestTemplate.Factory的实现类
        buildTemplate =
            new BuildFormEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
      } else if (md.bodyIndex() != null || md.alwaysEncodeBody()) {
        // BuildEncodedTemplateFromArgs 是RequestTemplate.Factory的实现类
        buildTemplate = new BuildEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
      } else {
        // BuildTemplateByResolvingArgs 是RequestTemplate.Factory的实现类
        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 {
        // factory 为SynchronousMethodHandler.Factory  来创建对应的 SynchronousMethodHandler
        result.put(md.configKey(),
            factory.create(target, md, buildTemplate, options, decoder, errorDecoder));
      }
    }
    return result;
  }
}