原生feign源码分析

feign的github官网见https://github.com/OpenFeign/feign
1、Feign.Builder 构造。可以指定以下参数进行替换

private final List<RequestInterceptor> requestInterceptors =
    new ArrayList<RequestInterceptor>(); // 默认为空列表
private Logger.Level logLevel = Logger.Level.NONE;
// NONE: No logging
// BASIC: Log only the request method and URL and the response status code and execution time
// HEADERS: Log the basic information along with request and response headers
// FULL: Log the headers, body, and metadata for both requests and responses
private Contract contract = new Contract.Default();// 解析interface到metadata,可使用SpringContract
private Client client = new Client.Default(null, null); // 默认使用HttpURLConnection调用接口,可以选择AacheHttpClient、OkHttpClient、RibbonClient、GoogleHttpClient等客户端库。
private Retryer retryer = new Retryer.Default();// 重试机制
private Logger logger = new NoOpLogger();// 推荐使用Slf4jLogger
private Encoder encoder = new Encoder.Default(); // 编码器JacksonEncoder、GsonEncoder等
private Decoder decoder = new Decoder.Default();// 解码器JacksonDecoder、GsonDecoder等
 private QueryMapEncoder queryMapEncoder = new FieldQueryMapEncoder();// FieldQueryMapEncoder、BeanQueryMapEncoder等
private ErrorDecoder errorDecoder = new ErrorDecoder.Default();// 除了200-300、404的其他状态处理
private Options options = new Options();// connectTimeoutMillis、readTimeoutMillis
private InvocationHandlerFactory invocationHandlerFactory =
    new InvocationHandlerFactory.Default();//feign.ReflectiveFeign.FeignInvocationHandler、feign.ReflectiveAsyncFeign.AsyncFeignInvocationHandler、feign.reactive.ReactiveInvocationHandler
private boolean closeAfterDecode = true; // AsyncResponseHandler使用
private ExceptionPropagationPolicy propagationPolicy = NONE; // NONE、UNWRAP 是否抛出异常原因
private boolean decode404;// 决定404使用decoder还是errorDecoder解析
private boolean forceDecoding = false; // decoder or asyncResponseHandler
private List<Capability> capabilities = new ArrayList<>();

2、feign.Feign.Builder#build 返回Feign的实现类ReflectiveFeign

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

3、feign.Feign.Builder#target(java.lang.Class, java.lang.String)

new HardCodedTarget<T>(apiType, url)  // 一个interface对应一个Target
build().newInstance(target)

4、feign.ReflectiveFeign#newInstance

Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target); // 根据contract解析interface
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);// 创建feign.ReflectiveFeign.FeignInvocationHandler
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),
    new Class<?>[] {target.type()}, handler);  // 生成代理类

for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
  defaultMethodHandler.bindTo(proxy);  // default 方法
}
return proxy;

5、github.contributors(“OpenFeign”, “feign”)

feign.ReflectiveFeign.FeignInvocationHandler feign.SynchronousMethodHandler feign.Client.Default HttpURLConnection dispatch.get(method).invoke(args) execute! 请求 返回 响应、解码 返回 feign.ReflectiveFeign.FeignInvocationHandler feign.SynchronousMethodHandler feign.Client.Default HttpURLConnection

6、Contract.parseAndValidateMetadata,存到MethodMetadata、Map<String, MethodHandler>

  class Default extends DeclarativeContract {

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

    public Default() {
    // 解析类@Header
      super.registerClassAnnotation(Headers.class, (header, data) -> {
        final String[] headersOnType = header.value();
        checkState(headersOnType.length > 0, "Headers annotation was empty on type %s.",
            data.configKey());
        final Map<String, Collection<String>> headers = toMap(headersOnType);
        headers.putAll(data.template().headers());
        data.template().headers(null); // to clear
        data.template().headers(headers);
      });
      // 解析方法@RequestLine
      super.registerMethodAnnotation(RequestLine.class, (ann, data) -> {
        final String requestLine = ann.value();
        checkState(emptyToNull(requestLine) != null,
            "RequestLine annotation was empty on method %s.", data.configKey());

        final 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",
              data.configKey()));
        } else {
          data.template().method(HttpMethod.valueOf(requestLineMatcher.group(1)));
          data.template().uri(requestLineMatcher.group(2));
        }
        data.template().decodeSlash(ann.decodeSlash());
        data.template()
            .collectionFormat(ann.collectionFormat());
      });
      // 解析方法@Body
      super.registerMethodAnnotation(Body.class, (ann, data) -> {
        final String body = ann.value();
        checkState(emptyToNull(body) != null, "Body annotation was empty on method %s.",
            data.configKey());
        if (body.indexOf('{') == -1) {
          data.template().body(body);
        } else {
          data.template().bodyTemplate(body);
        }
      });
      // 解析方法@Headers
      super.registerMethodAnnotation(Headers.class, (header, data) -> {
        final String[] headersOnMethod = header.value();
        checkState(headersOnMethod.length > 0, "Headers annotation was empty on method %s.",
            data.configKey());
        data.template().headers(toMap(headersOnMethod));
      });
      // 解析参数@Param
      super.registerParameterAnnotation(Param.class, (paramAnnotation, data, paramIndex) -> {
        final String name = paramAnnotation.value();
        checkState(emptyToNull(name) != null, "Param annotation was empty on param %s.",
            paramIndex);
        nameParam(data, name, paramIndex);
        final Class<? extends Param.Expander> expander = paramAnnotation.expander();
        if (expander != Param.ToStringExpander.class) {
          data.indexToExpanderClass().put(paramIndex, expander);
        }
        if (!data.template().hasRequestVariable(name)) {
          data.formParams().add(name);
        }
      });
      // 解析参数@QueryMap
      super.registerParameterAnnotation(QueryMap.class, (queryMap, data, paramIndex) -> {
        checkState(data.queryMapIndex() == null,
            "QueryMap annotation was present on multiple parameters.");
        data.queryMapIndex(paramIndex);
        data.queryMapEncoded(queryMap.encoded());
      });
      // 解析参数@HeaderMap
      super.registerParameterAnnotation(HeaderMap.class, (queryMap, data, paramIndex) -> {
        checkState(data.headerMapIndex() == null,
            "HeaderMap annotation was present on multiple parameters.");
        data.headerMapIndex(paramIndex);
      });
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值