1. Feign基本简介:

    Feign 受Retrofit、JAXRS-2.0 和Web Socket 的影响, 采用了声明式API 接口的风格, 将Java Http 客户端绑定到它的内部。
    Feign 的首要目标是将Java Http客户端调用过程变得简单。 Feign 的源码地址:https://github.com/OpenFeign/feign。4. FeignClient的配置
    Feign Client 默认的配置类为FeignClientsConfiguration , 这个类在spring-cloud-openfeign-core的jar 包下。
    打开这个类,可以发现这个类注入了很多Feign 相关的配置Bean ,包括FeignRetryer 、F eignLoggerF actory 和FormattingConversionService 等。
    另外, Decoder 、Encoder 和Contract这3 个类在没有Bean 被注入的情况下,会自动注入默认配置的Bean ,即ResponseEntity Decoder 、SpringEncoder 和SpringMvcContract。默认注入的配置如下。
    口Decoder feignDecoder: ResponseEntityDecoder。
    口Encoder feignEncoder: SpringEncoder 。
    口Logger feignLogger: Slf4jLogger 。
    口Contract feignContract: SpringMvcContract 。
    口Feign.Builder feignBuilder: HystrixFeign.Builder 。
    FeignClientsConfiguration 的配置类部分代码如下, @ConditionalOnMissingBean 注解表示如果没有注入该类的Bean 就会默认注入一个Bean 。

    重写FeignClientsConfiguration 类中的Bean , 覆盖掉默认的配置Bean ,从而达到自定义配置的目的。例如Feign 默认的配置在请求失败后, 重试次数为0 ,
    即不重试( Retry er.NEVER_RETRY )。现在希望在请求失败后能够重试,这时需要写一个配置FeignConfig 类,在该类中注入Retryer的Bean ,
    覆盖掉默认的Retryer的Bean , 并将FeignConfig 指定为FeignClient 的配置类。

5. Feign 是一个伪Java Http 客户端, Feign 不做任何的请求处理。Feign 通过处理注解生成Request 模板,从而简化了Http API 的开发。
   开发人员可以使用注解的方式定制Request API模板。在发送HttpRequest 请求之前, Feign 通过处理注解的方式替换掉Request 模板中的参数,
   生成真正的Request ,并交给Java Http 客户端去处理。利用这种方式,开发者只需要关注Feign注解模板的开发,而不用关注Http 请求本身,
   简化了Http 请求的过程,使得Http请求变得简单和容易理解。

   Feign 通过包扫描注入FeignClient 的Bean ,该源码在FeignClientsRegistrar 类中。首先在程序启动时,会检查是否有@EnableFeignClients 注解,
   如果有该注解,则开启包扫描,扫描被@FeignClient 注解的接口。
8. Feign如何实现负载均衡的:
    FeignRibbonClientAutoConfiguration 类配置了Client 的类型(包括HttpURLConnection 、OkHIttp 和HttpClient ),
    最终向容器注入的是Client 的实现类LoadBalancerFeignClient ,即负载均衡客户端。

7.  Feign流程总结:
      总的来说, Feign 的源码实现过程如下:
      ( 1) 首先通过@EnableFeignClients 注解开启Feign Client 的功能。只有这个注解存在,才会在程序启动时开启对@FeignClient 注解的包扫描。
      (2 )根据Feign 的规则实现接口,井在接口上面加上@FeignClient 注解。
      (3 )程序启动后,会进行包扫描,扫描所有的@ FeignClient 的注解的类,并将这些信息注入IoC 容器中。
      ( 4 )当接口的方法被调用时, 通过JDK 的代理来生成具体的RequestTemplate 棋根对象。
      ( 5 )根据RequestTemplate 再生成Http 请求的Request 对象。
      ( 6 ) Request 对象交给Client 去处理, 其中Client 的网络请求框架可以是HttpURLConnection 、HttpClient 和OkHttp 。
      (7 )最后Client 被封装到LoadBal a nceC li e n t 类,这个类结合类Ribbon 做到了负载均衡。