日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

33張圖探秘OpenFeign核心架構原理

來源: 責編: 時間:2024-02-29 14:42:48 263觀看
導讀大家好,我是三友~~在很久之前,我寫過兩篇關于OpenFeign和Ribbon這兩個SpringCloud核心組件架構原理的文章但是說實話,從我現在的角度來看,這兩篇文章的結構和內容其實還可以更加完善剛好我最近打算整個SpringCloud各個組

大家好,我是三友~~wPU28資訊網——每日最新資訊28at.com

在很久之前,我寫過兩篇關于OpenFeign和Ribbon這兩個SpringCloud核心組件架構原理的文章wPU28資訊網——每日最新資訊28at.com

但是說實話,從我現在的角度來看,這兩篇文章的結構和內容其實還可以更加完善wPU28資訊網——每日最新資訊28at.com

剛好我最近打算整個SpringCloud各個組件架構原理的小冊子wPU28資訊網——每日最新資訊28at.com

所以趁著這個機會,我就來重新寫一下這兩篇文章,彌補之前文章的不足wPU28資訊網——每日最新資訊28at.com

這一篇文章就先來講一講OpenFeign的核心架構原理wPU28資訊網——每日最新資訊28at.com

整篇文章大致分為以下四個部分的內容:wPU28資訊網——每日最新資訊28at.com

第一部分,脫離于SpringCloud,原始的Feign是什么樣的?wPU28資訊網——每日最新資訊28at.com

第二部分,Feign的核心組件有哪些,整個執行鏈路是什么樣的?wPU28資訊網——每日最新資訊28at.com

第三部分,SpringCloud是如何把Feign融入到自己的生態的?wPU28資訊網——每日最新資訊28at.com

第四部分,OpenFeign有幾種配置方式,各種配置方式的優先級是什么樣的?wPU28資訊網——每日最新資訊28at.com

好了,話不多說,接下來就直接進入主題,來探秘OpenFeign核心架構原理wPU28資訊網——每日最新資訊28at.com

原始Feign是什么樣的?

在日常開發中,使用Feign很簡單,就三步wPU28資訊網——每日最新資訊28at.com

第一步:引入依賴wPU28資訊網——每日最新資訊28at.com

<dependency>     <groupId>org.springframework.cloud</groupId>     <artifactId>spring-cloud-starter-openfeign</artifactId>     <version>2.2.5.RELEASE</version></dependency>

第二步:在啟動引導類加上@EnableFeignClients注解wPU28資訊網——每日最新資訊28at.com

@SpringBootApplication@EnableFeignClientspublic class MyApplication {    public static void main(String[] args) {        SpringApplication.run(MyApplication.class, args);    }}

第三步:寫個FeignClient接口wPU28資訊網——每日最新資訊28at.com

@FeignClient(name = "order")@RequestMapping("/order")public interface OrderApiClient {    @GetMapping    Order queryOrder(@RequestParam("orderId") Long orderId);}

之后當我們要使用時,只需要注入OrderApiClient對象就可以了wPU28資訊網——每日最新資訊28at.com

雖然使用方便,但這并不是Feign最原始的使用方式,而是SpringCloud整合Feign之后的使用方式wPU28資訊網——每日最新資訊28at.com

Feign最開始是由Netflix開源的wPU28資訊網——每日最新資訊28at.com

后來SpringCloud就將Feign進行了一層封裝,整合到自己的生態,讓Feign使用起來更加簡單wPU28資訊網——每日最新資訊28at.com

并同時也給它起了一個更高級的名字,OpenFeignwPU28資訊網——每日最新資訊28at.com

接下來文章表述有時可能并沒有嚴格區分Feign和OpenFeign的含義,你知道是這么個意思就行了。wPU28資訊網——每日最新資訊28at.com

Feign本身有自己的使用方式,也有類似Spring MVC相關的注解,如下所示:wPU28資訊網——每日最新資訊28at.com

public interface OrderApiClient {    @RequestLine("GET /order/{orderId}")    Order queryOrder(@Param("orderId") Long orderId);}

OrderApiClient對象需要手動通過Feign.builder()來創建wPU28資訊網——每日最新資訊28at.com

public class FeignDemo {    public static void main(String[] args) {        OrderApiClient orderApiClient = Feign.builder()                .target(OrderApiClient.class, "http://localhost:8088");        orderApiClient.queryOrder(9527L);    }}

Feign的本質:動態代理 + 七大核心組件

相信稍微了解Feign的小伙伴都知道,Feign底層其實是基于JDK動態代理來的wPU28資訊網——每日最新資訊28at.com

所以Feign.builder()最終構造的是一個代理對象wPU28資訊網——每日最新資訊28at.com

Feign在構建動態代理的時候,會去解析方法上的注解和參數wPU28資訊網——每日最新資訊28at.com

獲取Http請求需要用到基本參數以及和這些參數和方法參數的對應關系wPU28資訊網——每日最新資訊28at.com

比如Http請求的url、請求體是方法中的第幾個參數、請求頭是方法中的第幾個參數等等wPU28資訊網——每日最新資訊28at.com

之后在構建Http請求時,就知道請求路徑以及方法的第幾個參數對應是Http請求的哪部分數據wPU28資訊網——每日最新資訊28at.com

當調用動態代理方法的時候,Feign就會將上述解析出來的Http請求基本參數和方法入參組裝成一個Http請求wPU28資訊網——每日最新資訊28at.com

然后發送Http請求,獲取響應,再根據響應的內容的類型將響應體的內容轉換成對應的類型wPU28資訊網——每日最新資訊28at.com

這就是Feign的大致原理wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

在整個Feign動態代理生成和調用過程中,需要依靠Feign的一些核心組件來協調完成wPU28資訊網——每日最新資訊28at.com

如下圖所示是Feign的一些核心組件wPU28資訊網——每日最新資訊28at.com

這些核心組件可以通過Feign.builder()進行替換wPU28資訊網——每日最新資訊28at.com

由于組件很多,這里我挑幾個重要的跟大家講一講wPU28資訊網——每日最新資訊28at.com

1、Contract

圖片圖片wPU28資訊網——每日最新資訊28at.com

前面在說Feign在構建動態代理的時候,會去解析方法上的注解和參數,獲取Http請求需要用到基本參數wPU28資訊網——每日最新資訊28at.com

而這個Contract接口的作用就是用來干解析這件事的wPU28資訊網——每日最新資訊28at.com

Contract的默認實現是解析Feign自己原生注解的wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

解析時,會為每個方法生成一個MethodMetadata對象wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

MethodMetadata就封裝了Http請求需要用到基本參數以及這些參數和方法參數的對應關系wPU28資訊網——每日最新資訊28at.com

SpringCloud在整合Feign的時候,為了讓Feign能夠識別Spring MVC的注解,所以就自己實現了Contract接口wPU28資訊網——每日最新資訊28at.com

2、Encoder

通過名字也可以看出來,這個其實用來編碼的wPU28資訊網——每日最新資訊28at.com

具體的作用就是將請求體對應的方法參數序列化成字節數組wPU28資訊網——每日最新資訊28at.com

Feign默認的Encoder實現只支持請求體對應的方法參數類型為String和字節數組wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

如果是其它類型,比如說請求體對應的方法參數類型為AddOrderRequest.class類型,此時就無法對AddOrderRequest對象進行序列化wPU28資訊網——每日最新資訊28at.com

這就導致默認情況下,這個Encoder的實現很難用wPU28資訊網——每日最新資訊28at.com

于是乎,Spring就實現了Encoder接口wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

可以將任意請求體對應的方法參數類型對象序列化成字節數組wPU28資訊網——每日最新資訊28at.com

3、Decoder

Decoder的作用恰恰是跟Encoder相反wPU28資訊網——每日最新資訊28at.com

Encoder是將請求體對應的方法參數序列化成字節數組wPU28資訊網——每日最新資訊28at.com

而Decoder其實就是將響應體由字節流反序列化成方法返回值類型的對象wPU28資訊網——每日最新資訊28at.com

Decoder默認情況下跟Encoder的默認情況是一樣的,只支持反序列化成字節數組或者是StringwPU28資訊網——每日最新資訊28at.com

所以,Spring也同樣實現了Decoder,擴展它的功能wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

可以將響應體對應的字節流反序列化成任意返回值類型對象wPU28資訊網——每日最新資訊28at.com

4、Client

圖片wPU28資訊網——每日最新資訊28at.com

從接口方法的參數和返回值其實可以看出,這其實就是動態代理對象最終用來執行Http請求的組件wPU28資訊網——每日最新資訊28at.com

默認實現就是通過JDK提供的HttpURLConnection來的wPU28資訊網——每日最新資訊28at.com

除了這個默認的,Feign還提供了基于HttpClient和OkHttp實現的wPU28資訊網——每日最新資訊28at.com

在項目中,要想替換默認的實現,只需要引入相應的依賴,在構建Feign.builder()時設置一下就行了wPU28資訊網——每日最新資訊28at.com

SpringCloud環境底下會根據引入的依賴自動進行設置wPU28資訊網——每日最新資訊28at.com

除了上述的三個實現,最最重要的當然是屬于它基于負載均衡的實現wPU28資訊網——每日最新資訊28at.com

如下是OpenFeign用來整合Ribbon的核心實現wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

這個Client會根據服務名,從Ribbon中獲取一個服務實例的信息,也就是ip和端口wPU28資訊網——每日最新資訊28at.com

之后會通過ip和端口向服務實例發送Http請求wPU28資訊網——每日最新資訊28at.com

5、InvocationHandlerFactory

InvocationHandler我相信大家應該都不陌生wPU28資訊網——每日最新資訊28at.com

對于JDK動態代理來說,必須得實現InvocationHandler才能創建動態代理wPU28資訊網——每日最新資訊28at.com

InvocationHandler的invoke方法實現就是動態代理走的核心邏輯wPU28資訊網——每日最新資訊28at.com

而InvocationHandlerFactory其實就是創建InvocationHandler的工廠wPU28資訊網——每日最新資訊28at.com

所以,這里就可以猜到,通過InvocationHandlerFactory創建的InvocationHandler應該就是Feign動態代理執行的核心邏輯wPU28資訊網——每日最新資訊28at.com

InvocationHandlerFactory默認實現是下面這個wPU28資訊網——每日最新資訊28at.com

SpringCloud環境下默認也是使用它的這個默認實現wPU28資訊網——每日最新資訊28at.com

所以,我們直接去看看InvocationHandler的實現類FeignInvocationHandlerwPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

從實現可以看出,除了Object類的一些方法,最終會調用方法對應的MethodHandler的invoke方法wPU28資訊網——每日最新資訊28at.com

所以注意注意,這個MethodHandler就封裝了Feign執行Http調用的核心邏輯,很重要,后面還會提到wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

雖然說默認情況下SpringCloud使用是默認實現,最終使用FeignInvocationHandlerwPU28資訊網——每日最新資訊28at.com

但是當其它框架整合SpringCloud生態的時候,為了適配OpenFeign,有時會自己實現InvocationHandlerwPU28資訊網——每日最新資訊28at.com

比如常見的限流熔斷框架Hystrix和Sentinel都實現了自己的InvocationHandlerwPU28資訊網——每日最新資訊28at.com

這樣就可以對MethodHandler執行前后,也就是Http接口調用前后進行限流降級等操作。wPU28資訊網——每日最新資訊28at.com

6、RequestInterceptor

圖片圖片wPU28資訊網——每日最新資訊28at.com

RequestInterceptor它其實是一個在發送請求前的一個攔截接口wPU28資訊網——每日最新資訊28at.com

通過這個接口,在發送Http請求之前再對Http請求的內容進行修改wPU28資訊網——每日最新資訊28at.com

比如我們可以設置一些接口需要的公共參數,如鑒權token之類的wPU28資訊網——每日最新資訊28at.com

@Componentpublic class TokenRequestInterceptor implements RequestInterceptor {    @Override    public void apply(RequestTemplate template) {        template.header("token", "token值");    }}

7、Retryer

這是一個重試的組件,默認實現如下wPU28資訊網——每日最新資訊28at.com

默認情況下,最大重試5次wPU28資訊網——每日最新資訊28at.com

在SpringCloud下,并沒有使用上面那個實現,而使用的是下面這個實現wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

所以,SpringCloud下默認是不會進行重試wPU28資訊網——每日最新資訊28at.com

小總結

這一節主要是介紹了7個Feign的核心組件以及Spring對應的擴展實現wPU28資訊網——每日最新資訊28at.com

為了方便你查看,我整理了如下表格wPU28資訊網——每日最新資訊28at.com

接口wPU28資訊網——每日最新資訊28at.com

作用wPU28資訊網——每日最新資訊28at.com

Feign默認實現wPU28資訊網——每日最新資訊28at.com

Spring實現wPU28資訊網——每日最新資訊28at.com

ContractwPU28資訊網——每日最新資訊28at.com

解析方法注解和參數,將Http請求參數和方法參數對應wPU28資訊網——每日最新資訊28at.com

Contract.DefaultwPU28資訊網——每日最新資訊28at.com

SpringMvcContractwPU28資訊網——每日最新資訊28at.com

EncoderwPU28資訊網——每日最新資訊28at.com

將請求體對應的方法參數序列化成字節數組wPU28資訊網——每日最新資訊28at.com

Encoder.DefaultwPU28資訊網——每日最新資訊28at.com

SpringEncoderwPU28資訊網——每日最新資訊28at.com

DecoderwPU28資訊網——每日最新資訊28at.com

將響應體的字節流反序列化成方法返回值類型對象wPU28資訊網——每日最新資訊28at.com

Decoder.DefaultwPU28資訊網——每日最新資訊28at.com

SpringDecoderwPU28資訊網——每日最新資訊28at.com

ClientwPU28資訊網——每日最新資訊28at.com

發送Http請求wPU28資訊網——每日最新資訊28at.com

Client.DefaultwPU28資訊網——每日最新資訊28at.com

LoadBalancerFeignClientwPU28資訊網——每日最新資訊28at.com

InvocationHandlerFactorywPU28資訊網——每日最新資訊28at.com

InvocationHandler工廠,動態代理核心邏輯wPU28資訊網——每日最新資訊28at.com

InvocationHandlerFactory.DefaultwPU28資訊網——每日最新資訊28at.com

wPU28資訊網——每日最新資訊28at.com

RequestInterceptorwPU28資訊網——每日最新資訊28at.com

在發送Http請求之前,再對Http請求的內容進行攔截修改wPU28資訊網——每日最新資訊28at.com

wPU28資訊網——每日最新資訊28at.com

wPU28資訊網——每日最新資訊28at.com

RetryerwPU28資訊網——每日最新資訊28at.com

重試組件wPU28資訊網——每日最新資訊28at.com

Retryer.DefaultwPU28資訊網——每日最新資訊28at.com

wPU28資訊網——每日最新資訊28at.com

除了這些之外,還有一些其它組件這里就沒有說了wPU28資訊網——每日最新資訊28at.com

比如日志級別Logger.Level,日志輸出Logger,有興趣的可以自己查看wPU28資訊網——每日最新資訊28at.com

Feign核心運行原理分析

上一節說了Feign核心組件,這一節我們來講一講Feign核心運行原理,主要分為兩部分內容:wPU28資訊網——每日最新資訊28at.com

  • 動態代理生成原理
  • 一次Feign的Http調用執行過程

1、動態代理生成原理

這里我先把上面的Feign原始使用方式的Demo代碼再拿過來wPU28資訊網——每日最新資訊28at.com

public class FeignDemo {    public static void main(String[] args) {        OrderApiClient orderApiClient = Feign.builder()                .target(OrderApiClient.class, "http://localhost:8088");        orderApiClient.queryOrder(9527L);    }}

通過Demo可以看出,最后是通過Feign.builder().target(xx)獲取到動態代理的wPU28資訊網——每日最新資訊28at.com

而上述代碼執行邏輯如下所示:wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

最終會調用ReflectiveFeign的newInstance方法來創建動態代理對象wPU28資訊網——每日最新資訊28at.com

而ReflectiveFeign內部設置了前面提到的一些核心組件wPU28資訊網——每日最新資訊28at.com

接下我們來看看newInstance方法wPU28資訊網——每日最新資訊28at.com

這個方法主要就干兩件事:wPU28資訊網——每日最新資訊28at.com

第一件事首先解析接口,構建每個方法對應的MethodHandlerwPU28資訊網——每日最新資訊28at.com

MethodHandler在前面講InvocationHandlerFactory特地提醒過wPU28資訊網——每日最新資訊28at.com

動態代理(FeignInvocationHandler)最終會調用MethodHandler來處理Feign的一次Http調用wPU28資訊網——每日最新資訊28at.com

在解析接口的時候,就會用到前面提到的Contract來解析方法參數和注解,生成MethodMetadata,這里我代碼我就不貼了wPU28資訊網——每日最新資訊28at.com

第二件事通過InvocationHandlerFactory創建InvocationHandlerwPU28資訊網——每日最新資訊28at.com

然后再構建出接口的動態代理對象wPU28資訊網——每日最新資訊28at.com

ok,到這其實就走完了動態代理的生成過程wPU28資訊網——每日最新資訊28at.com

所以動態代理生成邏輯很簡單,總共也沒幾行代碼,畫個圖來總結一下wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

2、一次Feign的Http調用執行過程

前面說了,調用接口動態代理的方式時,通過InvocationHandler(FeignInvocationHandler),最終交給MethodHandler的invoke方法來執行wPU28資訊網——每日最新資訊28at.com

MethodHandler是一個接口,最終會走到它的實現類SynchronousMethodHandler的invoke方法實現wPU28資訊網——每日最新資訊28at.com

SynchronousMethodHandler中的屬性就是我們前面提到的一些組件wPU28資訊網——每日最新資訊28at.com

由于整個代碼調用執行鏈路比較長,這里我就不截代碼了,有興趣的可以自己翻翻wPU28資訊網——每日最新資訊28at.com

不過這里我畫了一張圖,可以通過這張圖來大致分析整個Feign一次Http調用的過程wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

  • 首先就是前面說的,進入FeignInvocationHandler,找到方法對應的SynchronousMethodHandler,調用invoke方法實現
  • 之后根據MethodMetadata和方法的入參,構造出一個RequestTemplate,RequestTemplate封裝了Http請求的參數,在這個過程中,如果有請求體,那么會通過Encoder序列化
  • 然后調用RequestInterceptor,通過RequestInterceptor對RequestTemplate進行攔截擴展,可以對請求數據再進行修改
  • 再然后將RequestTemplate轉換成Request,Request其實跟RequestTemplate差不多,也是封裝了Http請求的參數
  • 接下來通過Client去根據Request中封裝的Http請求參數,發送Http請求,得到響應Response
  • 最后根據Decoder,將響應體反序列化成方法返回值類型對象,返回

這就是Feign一次Http調用的執行過程wPU28資訊網——每日最新資訊28at.com

如果有設置重試,那么也是在這個階段生效的wPU28資訊網——每日最新資訊28at.com

SpringCloud是如何整合Feign的?

SpringCloud在整合Feign的時候,主要是分為兩部分wPU28資訊網——每日最新資訊28at.com

  • 核心組件重新實現,支持更多SpringCloud生態相關的功能
  • 將接口動態代理對象注入到Spring容器中

第一部分核心組件重新實現前面已經都說過了,這里就不再重復了wPU28資訊網——每日最新資訊28at.com

至于第二部分我們就來好好講一講,Spring是如何將接口動態代理對象注入到Spring容器中的wPU28資訊網——每日最新資訊28at.com

1、將FeignClient接口注冊到Spring中

使用OpenFeign時,必須加上@EnableFeignClientswPU28資訊網——每日最新資訊28at.com

這個注解就是OpenFeign的發動機wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

@EnableFeignClients最后通過@Import注解導入了一個FeignClientsRegistrarwPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

FeignClientsRegistrar實現了ImportBeanDefinitionRegistrarwPU28資訊網——每日最新資訊28at.com

所以最終Spring在啟動的時候會調用registerBeanDefinitions方法實現wPU28資訊網——每日最新資訊28at.com

之所以會調用registerBeanDefinitions方法,是@Import注解的作用,不清楚的同學可以看一下扒一扒Bean注入到Spring的那些姿勢,你會幾種?wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

最終會走到registerFeignClients這個方法wPU28資訊網——每日最新資訊28at.com

這個方法雖然比較長,主要是干了下面這個2件事:wPU28資訊網——每日最新資訊28at.com

第一件事,掃描@EnableFeignClients所在類的包及其子包(如果有指定包就掃指定包),找出所有加了@FeignClient注解的接口,生成一堆BeanDefinitionwPU28資訊網——每日最新資訊28at.com

這個BeanDefinition包含了這個接口的信息等信息wPU28資訊網——每日最新資訊28at.com

第二件事,將掃描到的這些接口注冊到Spring容器中wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

在注冊的時候,并非直接注冊接口類型,而是FeignClientFactoryBean類型wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

好了,到這整個@EnableFeignClients啟動過程就結束了wPU28資訊網——每日最新資訊28at.com

雖然上面寫的很長,但是整個@EnableFeignClients其實也就只干了一件核心的事wPU28資訊網——每日最新資訊28at.com

掃描到所有的加了@FeignClient注解的接口wPU28資訊網——每日最新資訊28at.com

然后為每個接口生成一個Bean類型為FeignClientFactoryBean的BeanDefinitionwPU28資訊網——每日最新資訊28at.com

最終注冊到Spring容器中wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

2、FeignClientFactoryBean的秘密

上一節說到,每個接口都對應一個class類型為FeignClientFactoryBean的BeanDefinitionwPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

如上所示,FeignClientFactoryBean是一個FactoryBeanwPU28資訊網——每日最新資訊28at.com

并且FeignClientFactoryBean的這些屬性,是在生成BeanDefinition的時候設置的wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

并且這個type屬性就是代表的接口類型wPU28資訊網——每日最新資訊28at.com

由于實現了FactoryBean,所以Spring啟動過程中,一定為會調用getObject方法獲取真正的Bean對象wPU28資訊網——每日最新資訊28at.com

FactoryBean的作用就不說了,不清楚的小伙伴還是可以看看扒一扒Bean注入到Spring的那些姿勢,你會幾種?這篇文章wPU28資訊網——每日最新資訊28at.com

getObject最終會走到getTarget()方法wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

從如上代碼其實可以看出來,最終還是會通過Feign.builder()來創建動態代理對象wPU28資訊網——每日最新資訊28at.com

只不過不同的是,SpringCloud會替換Feign默認的組件,改成自己實現的wPU28資訊網——每日最新資訊28at.com

總的來說,Spring是通過FactoryBean的這種方式,將Feign動態代理對象添加到Spring容器中wPU28資訊網——每日最新資訊28at.com

OpenFeign的各種配置方式以及對應優先級

既然Feign核心組件可以替換,那么在SpringCloud環境下,我們該如何去配置自己的組件呢?wPU28資訊網——每日最新資訊28at.com

不過在說配置之前,先說一下FeignClient配置隔離操作wPU28資訊網——每日最新資訊28at.com

在SpringCloud環境下,為了讓每個不同的FeignClient接口配置相互隔離wPU28資訊網——每日最新資訊28at.com

在應用啟動的時候,會為每個FeignClient接口創建一個Spring容器,接下來我就把這個容器稱為FeignClient容器wPU28資訊網——每日最新資訊28at.com

這些FeignClient的Spring容器有一個相同的父容器,那就是項目啟動時創建的容器wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

SpringCloud會給每個FeignClient容器添加一個默認的配置類FeignClientsConfiguration配置類wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

這個配置類就聲明了各種Feign的組件wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

所以,默認情況下,OpenFeign就使用這些配置的組件構建代理對象wPU28資訊網——每日最新資訊28at.com

知道配置隔離之后,接下來看看具體的幾種方式配置以及它們之間的優先級關系wPU28資訊網——每日最新資訊28at.com

1、通過@EnableFeignClients注解的defaultConfiguration屬性配置

舉個例子,比如我自己手動聲明一個Contract對象,類型為MyContractwPU28資訊網——每日最新資訊28at.com

public class FeignConfiguration {        @Bean    public Contract contract(){        return new MyContract();    }    }

注意注意,這里FeignConfiguration我沒加@Configuration注解,原因后面再說wPU28資訊網——每日最新資訊28at.com

此時配置如下所示:wPU28資訊網——每日最新資訊28at.com

@EnableFeignClients(defaultConfiguration = FeignConfiguration.class)

之后這個配置類會被加到每個FeignClient容器中,所以這個配置是對所有的FeignClient生效wPU28資訊網——每日最新資訊28at.com

并且優先級大于默認配置的優先級wPU28資訊網——每日最新資訊28at.com

比如這個例子就會使得FeignClient使用我聲明的MyContract,而不是FeignClientsConfiguration中聲明的SpringMvcContractwPU28資訊網——每日最新資訊28at.com

2、通過@FeignClient注解的configuration屬性配置

還以上面的FeignConfiguration配置類舉例,可以通過@FeignClient注解配置wPU28資訊網——每日最新資訊28at.com

@FeignClient(name = "order", configuration = FeignConfiguration.class)

此時這個配置類會被加到自己FeignClient容器中,注意是自己FeignClient容器wPU28資訊網——每日最新資訊28at.com

所以這種配置的作用范圍是自己的這個FeignClientwPU28資訊網——每日最新資訊28at.com

并且這種配置的優先級是大于@EnableFeignClients注解配置的優先級wPU28資訊網——每日最新資訊28at.com

3、在項目啟動的容器中配置

前面提到,由于所有的FeignClient容器的父容器都是項目啟動的容器wPU28資訊網——每日最新資訊28at.com

所以可以將配置放在這個項目啟動的容器中wPU28資訊網——每日最新資訊28at.com

還以FeignConfiguration為例,加上@Configuration注解,讓項目啟動的容器的掃描到就成功配置了wPU28資訊網——每日最新資訊28at.com

這種配置的優先級大于前面提到的所有配置優先級wPU28資訊網——每日最新資訊28at.com

并且是對所有的FeignClient生效wPU28資訊網——每日最新資訊28at.com

所以,這就是為什么使用注解配置時為什么配置類不能加@Configuration注解的原因,因為一旦被項目啟動的容器掃描到,這個配置就會作用于所有的FeignClient,并且優先級是最高的,就會導致你其它的配置失效,當然你也可以加@Configuration注解,但是一定不能被項目啟動的容器掃到wPU28資訊網——每日最新資訊28at.com

4、配置文件

除了上面3種編碼方式配置,OpenFeign也是支持通過配置文件的方式進行配置wPU28資訊網——每日最新資訊28at.com

并且也同時支持對所有FeignClient生效和對單獨某個FeignClient生效wPU28資訊網——每日最新資訊28at.com

對所有FeignClient生效配置:wPU28資訊網——每日最新資訊28at.com

feign:  client:    config:      default: # default 代表對全局生效        contract: com.sanyou.feign.MyContract

對單獨某個FeignClient生效配置:wPU28資訊網——每日最新資訊28at.com

feign:  client:    config:      order: # 具體的服務名        contract: com.sanyou.feign.MyContract

在默認情況下,這種配置文件方式優先級最高wPU28資訊網——每日最新資訊28at.com

但是如果你在配置文件中將配置項feign.client.default-to-properties設置成false的話,配置文件的方式優先級就是最低了wPU28資訊網——每日最新資訊28at.com

feign:  client:    default-to-properties: false

小總結

這一節,總共總結了4種配置OpenFeign的方式以及它們優先級和作用范圍wPU28資訊網——每日最新資訊28at.com

畫張圖來總結一下wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

如果你在具體使用的時候,還是遇到了一些優先級的問題,可以debug這部分源碼,看看到底生效的是哪個配置wPU28資訊網——每日最新資訊28at.com


wPU28資訊網——每日最新資訊28at.com

圖片圖片wPU28資訊網——每日最新資訊28at.com

圖片 wPU28資訊網——每日最新資訊28at.com

本文鏈接:http://m.www897cc.com/showinfo-26-75334-0.html33張圖探秘OpenFeign核心架構原理

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 在Golang中簡化日志記錄:提升性能和調試效率

下一篇: 使用原生cookieStore方法,讓Cookie操作更簡單

標簽:
  • 熱門焦點
Top 日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不
欧美在线免费播放| 亚洲免费影视| 欧美成人午夜激情在线| 欧美精品二区| 久久黄色影院| 亚洲一区二区三区四区中文 | 久久乐国产精品| 亚洲图片自拍偷拍| 亚洲欧洲在线观看| 国产亚洲欧美一区二区三区| 欧美日韩在线免费观看| 免费成人毛片| 久久久久久久国产| 久久gogo国模啪啪人体图| 蜜臀a∨国产成人精品| 欧美三区美女| 欧美香蕉视频| 欧美视频在线观看免费| 国产视频亚洲| 国产日韩精品一区二区三区在线| 国产精品乱人伦中文| 欧美日韩视频专区在线播放| 国产精品视频免费一区| 国产精品日韩高清| 在线播放豆国产99亚洲| 极品少妇一区二区三区| 狠色狠色综合久久| 樱桃成人精品视频在线播放| 正在播放亚洲一区| 亚洲综合视频在线| 亚洲午夜精品国产| 亚洲免费人成在线视频观看| 玖玖综合伊人| 另类天堂av| 国产精品久久久久久久久久妞妞| 欧美日韩亚洲一区二区三区| 欧美理论电影在线观看| 欧美激情bt| 欧美日韩国产在线观看| 国产精品久久久久三级| 亚洲大胆视频| 亚洲国产高清一区| 亚洲精品美女免费| 9国产精品视频| 一本久道久久综合狠狠爱| 亚洲激情在线激情| 亚洲激情影视| 欧美一区二粉嫩精品国产一线天| 久久久精品国产99久久精品芒果| 久久一区二区视频| 欧美日韩成人一区二区三区| 国产精品超碰97尤物18| 亚洲高清二区| 一本久道久久久| 日韩午夜激情电影| 欧美一区二区三区男人的天堂| 欧美在线一二三四区| 久热精品视频在线| 欧美国产高清| 国产精品久久久对白| 欧美日韩亚洲网| 国产精品私房写真福利视频| 国产欧美亚洲视频| 国产亚洲欧洲| 最近中文字幕日韩精品| 久久久精品日韩欧美| 国产日韩av在线播放| 亚洲永久免费观看| 欧美日韩在线大尺度| 亚洲精品在线三区| 欧美国产精品一区| 亚洲国产1区| 亚洲影院在线观看| 欧美四级在线观看| 一区二区欧美在线观看| 欧美日韩国产美女| 精品动漫3d一区二区三区免费| 亚洲人成在线免费观看| 性色av香蕉一区二区| 国产精品私拍pans大尺度在线| 亚洲一区二区三区在线| 国产精品啊v在线| 亚洲一区二区在线| 国产乱人伦精品一区二区| 亚洲国产天堂久久国产91| 久久香蕉国产线看观看av| 欧美色一级片| 亚洲高清视频的网址| 蜜臀a∨国产成人精品| 91久久久久久久久| 欧美日韩成人网| 宅男在线国产精品| 欧美成人a∨高清免费观看| 国产精品久久中文| 午夜精品av| 欧美日本一区二区视频在线观看| 黄色精品免费| 久久夜色撩人精品| 国产精品有限公司| 一区二区国产在线观看| 欧美视频免费在线观看| 亚洲影视综合| 国产午夜精品麻豆| 理论片一区二区在线| 亚洲国产欧美日韩精品| 欧美精品一区在线播放| 狠狠色综合日日| 亚洲中无吗在线| 国产日韩精品一区观看| 久热成人在线视频| 亚洲精品激情| 国产精品久久999| 欧美在线不卡视频| 亚洲国产天堂久久综合| 久久亚洲不卡| 日韩视频一区| 国产麻豆日韩欧美久久| 久久亚洲春色中文字幕久久久| 亚洲日本va午夜在线电影| 欧美婷婷六月丁香综合色| 日韩视频免费看| 国产精品视频第一区| 久久理论片午夜琪琪电影网| 亚洲精品一二三区| 欧美波霸影院| 一区二区三区我不卡| 欧美电影专区| 亚洲欧美日韩国产综合| 国产精品毛片va一区二区三区| 欧美自拍丝袜亚洲| 国产精品午夜久久| 另类专区欧美制服同性| 在线不卡视频| 老司机成人在线视频| 一区在线观看| 欧美视频你懂的| 久久精品三级| 精品91在线| 老牛影视一区二区三区| 亚洲少妇在线| 伊人久久婷婷色综合98网| 欧美丝袜一区二区| 午夜视频在线观看一区| 国产伦精品一区二区三区视频黑人| 亚洲一区在线直播| 1000部精品久久久久久久久| 欧美1区视频| 日韩手机在线导航| 欧美国内亚洲| 日韩视频中午一区| 欧美色综合天天久久综合精品| 久久成人精品一区二区三区| 国产一区二区三区自拍| 久久精品一本| 一区二区三区三区在线| 一区二区三区亚洲| 国产伦精品一区二区三区四区免费| 久久福利电影| 亚洲深夜福利视频| 亚洲国产日韩欧美在线图片| 国产欧美一区二区精品性色| 欧美精品久久一区| 久久久蜜桃精品| 亚洲欧美日韩在线| 精品91在线| 国产精品一区免费在线观看| 欧美激情一区二区三区| 久久久成人网| 在线日本高清免费不卡| 欧美日韩国产一区| 久久嫩草精品久久久精品| 亚洲欧美影院| 制服丝袜激情欧洲亚洲| 国产精品视频自拍| 欧美精品在线网站| 美女精品自拍一二三四| 久久成人免费电影| 亚洲女ⅴideoshd黑人| 国产在线视频不卡二| 久久精品日产第一区二区三区| 亚洲午夜伦理| 狠狠干综合网| 国产欧美短视频| 国产精品久久久久久久午夜片| 欧美精品在线观看一区二区| 久久综合中文字幕| 久久国产黑丝| 欧美一区二区三区在线看| 亚洲一区免费| 亚洲午夜精品久久久久久浪潮| 国产在线视频不卡二| 国产精品永久免费视频| 国产精品乱看| 国产精品视频免费一区| 国产精品久久久久久亚洲毛片| 另类尿喷潮videofree| 久久免费观看视频| 久久久久久亚洲精品杨幂换脸| 久久av最新网址| 久久精品视频网| 久久色中文字幕| 麻豆成人综合网| 女同一区二区| 欧美黄色成人网|