一、上文分析
前几篇文章,自己已经分析了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: 上面的代码细节不是很重要,其实是可以忽略的。其实目的就是
组装参数,设置重试,解析响应。