SpringCloud系列之Feign-6.Feign上下文构建解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud系列之Feign-6.Feign上下文构建解析相关的知识,希望对你有一定的参考价值。

参考技术A 1.首先在构建上下文的入口是在FeignClientFactoryBean的getObject方法

2.首先第一步就是构建了FeignContext类

3.然后我们进入到feign这个方法中看下:

可以看到首先获取两个日志对象一个FeignLoggerFactory,一个Logger,然后就是把这两个日志对象赋值给feign这个对象,我们看的Builder其实类似于方法糖,让赋值更加方便而已,类似于lombok中的@builder注解一样。

除了赋值日志对象以外,还有加密解密的一个赋值操作,这个是url解析过程中也是非常常见的。然后其他的我们暂时不关注,只要知道这里是初始化了feign对象,一个空的对象,构造器。

4.然后我们继续在主方法往下走

在上一个帖子上我们注意到url是空的,那么在这里就需要使用到了,从源码中看到如果url是空的,那么就使用服务名称作为ip了,然后如果不是http开头,这里就会给一个http的前缀上去,因为feign也是基于eureka的http接口的。

我们在看下下一个方法啊 cleanPaht();

这里其实还是拼装url的操作,在@FeignClient注解中有一个path的属性,这个属性干嘛用的呢,如图:

而这个path我们最后是不需要/的,所以这里其实就是格式化一下而已,正确的拼接好url的操作。

5.主方法继续

这里就是构造动态代理对象的地方了。

我们点进去看:

可以看到首先调用了getOptional这个方法,然后使用了

传入了一个调用的服务名称就是 eureka-client这个服务名称,还有一个 feign.Client的类。

其实这个方法就是从上下文中拿到调用了这个服务的接口作为一个client。

然后把client放到Feign对象中,再构建一个Targeter类

6.然后我们进入targeter.target这个方法看看这个最核心的地方

这块逻辑做了一个判断,看这个feign是不是hystrix的feign,如果是就走上面的逻辑,否则就走下面的逻辑,降级熔断啊之类的逻辑,但我们注意到不论走哪个,最终都会走feign.target(target);

7.然后我们进入 feign.target 这个方法:

我们继续进入newInstance这个方法:

上面的三个方法没看懂,我们暂且跳过,看到target通过断点我们可以知道,type就是IService,getMethods就是获取到了FeignClient那个接口下面的所有方法了,现在就是遍历所有方法了,我们现在懂点看下遍历中做的逻辑是什么

8.首先进行判断,看他是对象吗,显然这个是方法不是对象所以跳过,然后Util.isDefault(method)我们看下:

看着大致意思就是判断这个是不是接口而且修饰符必须是这几种;

所以这个判断也没进去,最后执行了下面这个方法:

我们查看下Feign.configKey(target.type(), method) 这个是什么:

发现是这个FeignClient接口的名称#方法名称;

所以这里就在methodToHandler.put如一个方法,还有方法的Handler,所以说这个接口虽然没有实现类,但是转发到了其他的实现类中,那么这个实现类到底是什么,我们继续往下面看:

然后就把这个handler作为参数创建了一个代理proxy并返回,然后如果我们通过Feign访问的话其实访问的就是代理proxy,但是最终干活的其实就是handler。

以上是关于SpringCloud系列之Feign-6.Feign上下文构建解析的主要内容,如果未能解决你的问题,请参考以下文章

SpringCloud系列之自定义GatewayFilterFactory

重学SpringCloud系列二之服务注册与发现---上

重学SpringCloud系列三之服务注册与发现---下

重学SpringCloud系列四之分布式配置中心---上

SpringCloud系列之三---Ribbon负载均衡使用

重学SpringCloud系列五之服务注册与发现---中