Feign是一個聲明式的Web服務客戶端。這使得Web服務客戶端的寫入更加方便 要使用Feign建立一個界面並對其進行註釋。它具備可插拔註釋支持,包括Feign註釋和JAX-RS註釋。Feign還支持可插拔編碼器和解碼器。Spring Cloud添加了對Spring MVC註釋的支持,並在Spring Web中使用默認使用的HttpMessageConverters。Spring Cloud集成Ribbon和Eureka以在使用Feign時提供負載均衡的http客戶端。java
在介紹spring cloud feign以前,先來看看原生的feign,而後在看spring cloud feign是怎麼樣集成原生的feign的。git
1、原生的feign的用法github
一、引入jarspring
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-gson</artifactId> <version>9.5.0</version> </dependency>
二、編寫代碼,如下是發送GET和POST請求方式(更多請查看)apache
public class FeignTest { interface BookService{ @RequestLine("GET /book/borrow?name={name}&timeout={timeout}") String borrow(@Param("name")String name,@Param("timeout")Integer timeout); @RequestLine("POST /book/post") @Headers("Content-Type: application/json") @Body("%7B\"id\": \"{id}\", \"name\": \"{name}\"%7D") String post(@Param("id")String id,@Param("name")String name); } public static void main(String[] args) { BookService bs = Feign.builder() .options(new Options(2000, 6000)) .target(BookService.class, "http://localhost:2001"); String result = bs.borrow("2w2w",1); System.out.println(result); result = bs.post("12345", "spring feign"); System.out.println(result); } }
feign核心類介紹編程
feign.Feign.Builder 設置發送http請求的相關參數,好比http客戶端,重試策略,編解碼,超時時間等等json
在上述示例代碼中,到底feign給我作了哪些事情呢?下面的時序圖爲咱們展現整個處理過程api
一、經過feign.Feign.Builder爲咱們設置http請求的相關參數,好比http客戶端,重試策略,編解碼,超時時間,這裏都是面向接口編程實現的,咱們很容易的進行擴展,好比http客戶端,可使用java原生的實現,也可使用apache httpclient,亦可使用okHttpClient,本身喜歡就好,其餘屬性亦是如此,由此看出feign的設計具備很是好的可擴展性。mvc
二、ReflectiveFeign內部使用了jdk的動態代理爲目標接口生成了一個動態代理類,這裏會生成一個InvocationHandler(jdk動態代理原理)統一的方法攔截器,同時爲接口的每一個方法生成一個SynchronousMethodHandler攔截器,並解析方法上的 元數據,生成一個http請求模板。app
三、當發起方法調用的時候,被統一的方法攔截器FeignInvocationHandler攔截,再根據不一樣的方法委託給不一樣的SynchronousMethodHandler攔截器處理。
四、根據每次方法調用的入參生成http請求模板,若是設置了http請求攔截器,則先經歷攔截器的處理,再發起真正的http請求,獲得結果後會根據方法放入返回值進行反序列化,最後返回給調用方。
五、若是發生了異常,會根據重試策略進行重試。
feign也整合了Hystrix,實現熔斷降級的功能,其實也很簡單,上面的分析咱們知道了feign在方法調用的時候會通過統一方法攔截器FeignInvocationHandler的處理,而HystrixFeign則是使用了HystrixInvocationHandler代替,在方法調用的時候進行Hystrix的封裝,這裏須要特別說明下:
以上就是原生feign的基本原理,下面咱們來分析下springcloud是如何進行整合進來的,又添加了一些什麼東西?
spring-cloud-feign的基本用法:
一、開啓註解EnableFeignClients
@EnableFeignClients public class ApplicationStartup { public static void main(String[] args) { SpringApplication.run(ApplicationStartup.class, args); } }
二、定義接口
@FeignClient(name = "user") public interface IUserService{ @RequestMapping(value = "/api/getUser") User getUser(Long id); }
三、這樣經過spring注入IUserService就可使用了
@Controller public class UserController { @Autowired private IUserService userService; }
使用起來很是簡單,核心的兩步就是開啓註解,定於feignclient接口。
1、開啓@EnableFeignClients註解到底給咱們作了什麼事情呢?
一、掃描EnableFeignClients註解上的配置信息,註冊默認的配置類,這個配置類是對全部feignclient的都是生效的,即爲全局的配置。
二、掃描帶有@FeignClient註解的接口,並註冊配置類(此時的配置類針對當前feignclient生效)和FeignClientFactoryBean,此bean實現了FactoryBean接口,咱們知道spring有兩種類型的bean對象,一種是普通的bean,另外一種則是工廠bean(FactoryBean),它返回的實際上是getObject方法返回的對象(更多關於FactoryBean的相關信息請查看spring官方文檔)。getObject方法就是集成原生feign的核心方法,當spring注入feignclient接口時,getObject方法會被調用,獲得接口的代理類。
2、自動加載配置類FeignAutoConfiguration,FeignClientsConfiguration,FeignRibbonClientAutoConfiguration,這三個類爲feign提供了全部的配置類,默認狀況下所加載的類狀況:
feign.Client 此實現類的加載分兩種狀況:
feign.Request.Options 默認設置鏈接超時時間是10,讀超時時間是60s。這裏也能夠更改,分兩種狀況:
使用url方式:必須經過這個參數來設置,才生效
@Configuration public class MyConfig { @Bean public Request.Options options(){ Request.Options o = new Options(1000, 1000); return o; } }
而後在註解上@FeignClient指定:
@FeignClient(name="",url="",configuration= {MyConfig.class})
注意此類不能被spring容器掃描到,不然會對全局生效。你也能夠經過註解@EnableFeignClients來全局指定:
@EnableFeignClients(defaultConfiguration=MyConfig.class)
使用name方式:此時已經集成了ribbon,可使用如下配置來設置,若是你此時也配置了Options,如下配置會被覆蓋
# 對全部的feignclient生效 ribbon.ReadTimeout=10000 ribbon.ConnectTimeout=2000 # 對指定的feignclien生效 [feignclientName].ribbon.ReadTimeout=10000 [feignclientName].ribbon.ConnectTimeout=2000
若是開啓Hytrix,hytrix也有超時時間設置,可是hytrix是封裝在feign基礎之上的,上文已有分析。
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=10000
你也能夠關閉hytrix的超時時間
hystrix.command.default.execution.timeout.enabled=false
最後三種也是spring-cloud-feign替換原生feign的默認實現,對springMVC的相關支持,會另有文章進行解析。
spring-cloud-feign的核心源碼解析到此結束了,不知道是否對您有無幫助,可留言跟我交流。