Feign源码学习(5)— 开始分析feign的请求流程

503 阅读2分钟

一、上文分析

前几篇文章,自己已经分析了feign的源码要经历的事情。

1. @feingn 注解扫描对应的feign的interface   
2. 构造属于自己服务的Feign.Builder
3. 通过JDK 动态代理,生成代理的target   
4. 创建好MethodHandler, 来专门来处理Feign的调用

二、Feign的请求流程

上面只是对Feign的源码总结调用,现在下面就真正地跑一次断点,看看程序的具体流程是如何?

那么,从哪里入手呢?之前分析过,Feign是通过JDK 动态代理来创建一个代理对象,是T proxy, 然后这个T proxy对象 都会给到 InvokecationHandler的实现类invoke 方法去执行。

那么。就找到 ReflectiveFeign#invoke 方法给到断点

2.1 invoke 方法的分析

这里非常简单,一定是执行 dispatch.get(method).invoke(args); 这行代码。

PS: 假设说feign类是有个方法是 sayHello , 只可能会走到这行代码。

2.2 dispatch.get(method).invoke(args) 代码分析

首先看, dispatch 是什么?

直接上代码

Map<Method, MethodHandler> dispatch;

key 是方法要执行的方法名, value是方法的handler, 每个方法的执行就是交给 MethodHandler 来去执行。

然后再去调用 MethodHandler.invoke 方法

2.3 MethodHandler.invoke 分析

OK, 直接上代码:
这里注意的是真正调用的时候是调用到了 SynchronousMethodHandler.invoke 方法。 因为MethodHandler 只是一个接口。我们要看实现类的invoke

OK, 代码如下:

 @Override
  public Object invoke(Object[] argv) throws Throwable {
  // 构建出一个 RequestTemplate, 那么里面是作了啥?  
    RequestTemplate template = buildTemplateFromArgs.create(argv);
    // 设置对应的重试次数
    Retryer retryer = this.retryer.clone();
    while (true) {
      try {
       	// 执行对应的发送http 请求
        return executeAndDecode(template);
      } 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;
      }
    }
  }

代码分析:

RequestTemplate template = buildTemplateFromArgs.create(argv);
这个方法主要是将参数进行构建,然后发送一个RestTemplate的请求。

紧接着,设置对应的重试的次数。

   // 设置对应的重试次数
    Retryer retryer = this.retryer.clone();

最后,就是发送Http 请求,然后去解析response了,

PS: 上面的代码细节不是很重要,其实是可以忽略的。其实目的就是
组装参数,设置重试,解析响应