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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

原始Feign是什么樣的?

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

OrderApiClient對象需要手動通過Feign.builder()來創建FxL28資訊網——每日最新資訊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動態代理來的FxL28資訊網——每日最新資訊28at.com

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

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

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

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

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

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

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

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

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

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

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

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

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

1、Contract

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

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

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

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

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

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

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

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

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

2、Encoder

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

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

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

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

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

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

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

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

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

3、Decoder

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

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

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

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

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

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

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

4、Client

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

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

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

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

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

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

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

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

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

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

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

5、InvocationHandlerFactory

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

6、RequestInterceptor

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

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

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

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

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

7、Retryer

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

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

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

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

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

小總結

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Feign核心運行原理分析

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

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

1、動態代理生成原理

這里我先把上面的Feign原始使用方式的Demo代碼再拿過來FxL28資訊網——每日最新資訊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)獲取到動態代理的FxL28資訊網——每日最新資訊28at.com

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

圖片圖片FxL28資訊網——每日最新資訊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調用的執行過程FxL28資訊網——每日最新資訊28at.com

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

SpringCloud是如何整合Feign的?

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

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

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

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

1、將FeignClient接口注冊到Spring中

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2、FeignClientFactoryBean的秘密

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@EnableFeignClients(defaultConfiguration = FeignConfiguration.class)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

4、配置文件

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

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

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

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

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

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

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

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

feign:  client:    default-to-properties: false

小總結

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

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

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

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


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

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

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

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

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

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

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

標簽:
  • 熱門焦點
  • K60至尊版狂暴引擎2.0加持:超177萬跑分斬獲性能第一

    Redmi的后性能時代戰略發布會今天下午如期舉辦,在本次發布會上,Redmi公布了多項關于和聯發科的深度合作,以及新機K60 Ultra在軟件和硬件方面的特性,例如:“K60 至尊版,雙芯旗艦
  • 一篇聊聊Go錯誤封裝機制

    %w 是用于錯誤包裝(Error Wrapping)的格式化動詞。它是用于 fmt.Errorf 和 fmt.Sprintf 函數中的一個特殊格式化動詞,用于將一個錯誤(或其他可打印的值)包裝在一個新的錯誤中。使
  • 學習JavaScript的10個理由...

    作者 | Simplilearn編譯 | 王瑞平當你決心學習一門語言的時候,很難選擇到底應該學習哪一門,常用的語言有Python、Java、JavaScript、C/CPP、PHP、Swift、C#、Ruby、Objective-
  • 讓我們一起聊聊文件的操作

    文件【1】文件是什么?文件是保存數據的地方,是數據源的一種,比如大家經常使用的word文檔、txt文件、excel文件、jpg文件...都是文件。文件最主要的作用就是保存數據,它既可以保
  • .NET 程序的 GDI 句柄泄露的再反思

    一、背景1. 講故事上個月我寫過一篇 如何洞察 C# 程序的 GDI 句柄泄露 文章,當時用的是 GDIView + WinDbg 把問題搞定,前者用來定位泄露資源,后者用來定位泄露代碼,后面有朋友反
  • 自研Exynos回歸!三星Galaxy S24系列將提供Exynos和驍龍雙版本

    年初,全新的三星Galaxy S23系列發布,包含Galaxy S23、Galaxy S23+和Galaxy S23 Ultra三個版本,全系搭載超頻版驍龍8 Gen 2,雖同樣采用臺積電4nm工藝制
  • 2299元起!iQOO Pad開啟預售:性能最強天璣平板

    5月23日,iQOO如期舉行了新品發布會,除了首發安卓最強旗艦處理器的iQOO Neo8系列新機外,還在發布會上推出了旗下首款平板電腦——iQOO Pad,其搭載了天璣
  • “買真退假” 這種“羊毛”不能薅

    □ 法治日報 記者 王春   □ 本報通訊員 胡佳麗  2020年初,還在上大學的小東加入了一個大學生兼職QQ群。群主&ldquo;七王&rdquo;在群里介紹一些刷單賺
  • 榮耀Magic4 至臻版 首創智慧隱私通話 強勁影音系統

    2022年第一季度臨近尾聲,在該季度內,許多品牌陸續發布自己的最新產品,讓大家從全新的角度來了解當今的手機技術。手機是電子設備中,更新迭代十分迅速的一款產品,基
Top 主站蜘蛛池模板: 界首市| 南投市| 广河县| 墨竹工卡县| 武威市| 高密市| 安陆市| 苏州市| 姚安县| 福鼎市| 铜山县| 宣汉县| 漯河市| 南宫市| 溧水县| 乐业县| 东辽县| 桐梓县| 松阳县| 巴里| 雷波县| 辽宁省| 东安县| 盘山县| 万年县| 遂川县| 新源县| 诏安县| 桑日县| 报价| 萍乡市| 麻阳| 印江| 阜城县| 托里县| 城固县| 湖北省| 遂川县| 通道| 鄂州市| 桃园县|