![0c12f97a919c1bb7c8e70152779510a0.png](https://i-blog.csdnimg.cn/blog_migrate/0226fb085b52f927567df3eb9ce07515.png)
一.简介
Feign受Retrofit、JAXRS-2.0和WebSocket的影响,采用了声明式API接口,将Java Http客户端绑定到它的内部。Feign的首要目标是将Java Http客户端调用过程变得简单。Feign源码地址:https://github.com/OpenFeign/feign
本文参考了网络内容和书籍内容,仅为个人学习笔记。
1.创建一个Feign客户端
引入依赖:
<
配置application.yml:
server:
启动类:
@EnableEurekaClient
创建FeignClient接口:
@FeignClient
创建FeignConfig:
@Configuration
创建FeignClientImpl:
@Service
创建FeignController:
@RestController
启动eureka-server(8888)和两个eureka-client(8080,8081),在浏览器上面访问http://localhost:8060/hello/feign,多次访问,将会发现轮番调用。由此可见Feign Client有负载均衡能力。如果查看spring-cloud-starter-feign的pom文件,可以看到该起步依赖默认引入了Ribbon和Hystrix的依赖。
二.FeignClient详解
1.FeignClient注解
@Target
- @Target({ElementType.TYPE}) :表明FeignClient注解的作用目标在接口上
- @Retention(RetentionPolicy.RUNTIME) :表明该注解会在Class字节码文件中存在,在运行是可以通过反射获取到。
@FeignClient注解用于创建声明式API接口,该接口是Restful风格的,Feign被设计成插拔式的,可以注入其它组件和Feign一起使用。比如Ribbon,Feign和Ribbon相结合进行负载均衡。
- value()和name()是被调用服务的ServiceId
- url()直接填写硬编码的Urldiz
- decode404()即404是被解码
- configuration()指明FeignClient的配置类,默认的配置类为FeignClientsConfiguration类
- fallBack()为配置熔断器的处理类
2.FeignClient的配置
Feign Client默认的配置类为FeignClientsConfiguration,注入了很多@Bean,如果没有相应的Bean将会注入默认。
@Configuration
3.覆盖默认Bean实例
Feign默认的配置在请求失败后,重试次数为0(Retryer.NEVER_RETRY)。现在更改为重试间隔100毫秒,最大重试间隔1秒,重试次数为5此。
@Configuration
三.简单源码
Feign是一个伪Java HTTP客户端,Feign不做任何的请求处理。Feign通过处理注解生成Request模板,从而简化HTTP API的开发。开发人员可以使用注解的方式定制Request API模板。在发送HTTP Request请求之前,Feign通过处理注解的方式替换掉Request模板中的参数,生成真正的Request,并交给HTTP客户端去处理。利用这种方式,开发者只需要关注Feign注解模板的开发,而不用关注HTTP本身,简化了HTTP请求的过程,使HTTP请求变得简单和容易理解。
总体来说,Feign的源码实现过程:
- @EnableFeignClients开启FeignClient的功能
- 实现Feign接口(在接口上面加@FeignClient)
- 程序启动后,扫描所有的@FeignClient类,放到IoC容器中
- 当接口被调用,通过代理生产RequestTemplate模板
- 根据RequestTemplate模板生产HTTP请求的Request对象
- Client处理Request对象
- 最后LoadBalanceClient结合Ribbon进行负载均衡
1.FeignClientsRegistrar
Feign通过包扫描注入FeignClient的Bean。程序启动时扫描@EnableFeignClients注解,开启包扫描,扫描被@FeignClient注解的接口。
private
2.注入IoC容器
当在启动类中标注@EnableFeignClients注解,程序会将@FeignClient休息的接口、接口名、注解的信息一起取出,赋给BeanDefinitionBuilder,然后根据BeanDefinitionBuilder得到BeanDefinition,最后将BeanDefinition注入IoC容器。
public
3.ReflectiveFeign
注入BeanDefinition后,调用Feign Client接口里面的方法,通过代理进行拦截。
public
4.生成RequestTemplate对象
SynchronousMethodHandler类进行拦截,生成RequestTemplate模板对象。
public
5.Client
在Feign中,Client是一个非常重要的组件,Feign最终发送的Request请求以及接受Response响应都是由Client组件完成的。Client在Feign源码中是一个接口,在默认情况下,Client的实现类是Client.Default,Client.Default是由HttpURLConnection来实现网络请求的。另外Client还支持HttpClient和OKHttp来进行网络请求。
四.Feign实现负载均衡
FeignRibbonClientAutoConfiguration类配置了Client的类型,最终向容器中注入的是Client的实现类LoadBalancerFeignClient。通过LoadBalancerFeignClient中的execute方法来执行请求。
public