Feign 运用与源码解析

Feign

FeignClient注解分析

@Target(ElementType.TYPE)修饰,表示FeignClient注解的作用目标在接口上,简单的介绍下各个属性。value(), name()都是一样的,都是定义的serviceId。uri()直接写硬编码的地址,一般用来调试用,decode404()针对返回结果404被解码或者抛异常。configuration()为feign的配置类,默认的配置类为FeignClientsConfiguration,fallback()为相关的熔断类。

FeignClient运行原理

主程序上添加@EnableFeignClients这个注解,启动时会自动加载feign的相关配置,并且扫描带有@FeignClient的类,源码在FeignClientsRegistrar类里

registerFeignClients这个方法扫描所有带有@FeignClient注解的类

获取到相关的基础配置,最后赋值给BeanDefinitionBuilder,得到BeanDefinition,注入到IOC容器中。之后通过JDK代理,在调用feign client接口方法的时候,就会被拦截,源码在ReflectiveFeign。

通过jdk代理新建个实例。在SynchronousMethodHandler进行拦截,根据参数生成一个基于http的RequestTemplate对象。

调用了executeAndDecode()这个方法,这个方法是根据参数生成一个request请求对象,通过http client获取response。

feign的负载均衡

查看一下LoadBalancerFeignClient,其中的execute方法。

代码中执行了executeWithLoadBalancer方法,这个方法里又调用了LoadBalancerCommand类中的submit方法

submit方法又调用了selectServer这个方法

由该方法进行选择负载均衡的方法,最终负载均衡交给loadBalancerContext来处理,也就是ribbon。

Server server = LoadBalancerCommand.this.loadBalancerContext.getServerFromLoadBalancer(LoadBalancerCommand.this.loadBalancerURI, LoadBalancerCommand.this.loadBalancerKey);

feign的工作流程总结如下:

1-主程序启动扫描EnableFeignClients这个注解。

2-接下来扫描FeignClient注解。

3-在调用有FeignClient注解标注的接口,开启jdk代理,生成一个requestTemplate对象。

4-这个request请求交给Client去处理,去判断使用HttpClient,OkHttp 还是默认的HttpURLConnection框架。

5-client类被封装到LoadBalancerClient类里,通过ribbon实现负载均衡。

你可能感兴趣的:(Feign 运用与源码解析)