feign分析第二篇

534 阅读2分钟

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

RequestInterceptor

请求拦截器,在请求发送之前,对RequestTemplate 做出修改, 例如: 修改请求头, 请求参数等

void apply(RequestTemplate template);

参数RequestTemplate:请求HTTP目标的构建器。这个类是UriTemplate的一个变体,其中,除了uri, header和Query信息也支持模板表达式。

Logger

用于调试消息的简单日志抽象, 适配器模式,Slf4jLogger是个适配器角色, Logger(slf4j)是待适配的接口, Logger(Feign)是目标接口

02logger1.jpg

Contract

定义哪些注释和值在接口上是有效的。

List<MethodMetadata> parseAndValidateMetadata(Class<?> targetType); 调用来解析链接到HTTP请求的类中的方法。

MethodMetadata 方法的元数据对象 ,包含`RequestTemplate

02contract1.jpg

Options

参数Options,配置信息封装,包含:connectTimeout,connectTimeoutUnit,readTimeout,readTimeoutUnit,followRedirects(是否重定向)

Encoder

对HTTP请求体 进行编码,序列化方式的抽象

void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException;

将object 转换到 template.body中 Request.Body 包含字节数组和编码方式

02encoder1.jpg

Decoder

将HTTP响应解码为给定的单个对象(反序列化)

Object decode(Response response, Type type) throws IOException, DecodeException, FeignException; 将response中的内容解析, 返回值 为 Type类型的类对象, Type就是 定义的 FeignClient接口中的 方法的返回值类型描述

02decoder1.jpg

QueryMapEncoder

QueryMapEncoder将对象编码为查询参数名称到值的映射。 即 拼接到 Url后

例如: www.baidu.com?q=1&name=张三

Map<String, Object> encode(Object object); 将对象转换为map

02QueryMapEncoder1.jpg

ErrorDecoder

当响应结果不是2XX,404的时候, 会执行ErrorDecoder,如果需要重试,则返回RetryableException

Exception decode(String methodKey, Response response)

实现此方法,以便解码HTTP {@link Response}时

{@link Response#status()}不在2xx范围内。请引发特定于应用程序的异常

在可能的情况下。如果你的异常是可重试的,wrap或子类{@link RetryableException}

Target

类似于 javax.ws.rs.client.WebTarget

为 FeignClient的接口

Class<T> type(); 此目标所应用的接口类型

String name(); 与此目标关联的配置键。

String url();目标器的base HTTP URL。

Request apply(RequestTemplate input) 将模版转换为Request

02target1.jpg

EmptyTarget: 空实现

HardCodedTarget:硬编码

MockTarget: mock实现

LoadBalancingTarget: 负载均衡Target,对url进行动态替换

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;
      }
    }
  }