偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

33張圖探秘OpenFeign核心架構(gòu)原理

開發(fā) 架構(gòu)
當(dāng)調(diào)用動(dòng)態(tài)代理方法的時(shí)候,F(xiàn)eign就會(huì)將上述解析出來的Http請(qǐng)求基本參數(shù)和方法入?yún)⒔M裝成一個(gè)Http請(qǐng)求,然后發(fā)送Http請(qǐng)求,獲取響應(yīng),再根據(jù)響應(yīng)的內(nèi)容的類型將響應(yīng)體的內(nèi)容轉(zhuǎn)換成對(duì)應(yīng)的類型‘’這就是Feign的大致原理。

大家好,我是三友~~

在很久之前,我寫過兩篇關(guān)于OpenFeign和Ribbon這兩個(gè)SpringCloud核心組件架構(gòu)原理的文章

但是說實(shí)話,從我現(xiàn)在的角度來看,這兩篇文章的結(jié)構(gòu)和內(nèi)容其實(shí)還可以更加完善

剛好我最近打算整個(gè)SpringCloud各個(gè)組件架構(gòu)原理的小冊(cè)子

所以趁著這個(gè)機(jī)會(huì),我就來重新寫一下這兩篇文章,彌補(bǔ)之前文章的不足

這一篇文章就先來講一講OpenFeign的核心架構(gòu)原理

整篇文章大致分為以下四個(gè)部分的內(nèi)容:

第一部分,脫離于SpringCloud,原始的Feign是什么樣的?

第二部分,F(xiàn)eign的核心組件有哪些,整個(gè)執(zhí)行鏈路是什么樣的?

第三部分,SpringCloud是如何把Feign融入到自己的生態(tài)的?

第四部分,OpenFeign有幾種配置方式,各種配置方式的優(yōu)先級(jí)是什么樣的?

好了,話不多說,接下來就直接進(jìn)入主題,來探秘OpenFeign核心架構(gòu)原理

原始Feign是什么樣的?

在日常開發(fā)中,使用Feign很簡(jiǎn)單,就三步

第一步:引入依賴

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

第二步:在啟動(dòng)引導(dǎo)類加上@EnableFeignClients注解

@SpringBootApplication
@EnableFeignClients
public class MyApplication {

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

}

第三步:寫個(gè)FeignClient接口

@FeignClient(name = "order")
@RequestMapping("/order")
public interface OrderApiClient {

    @GetMapping
    Order queryOrder(@RequestParam("orderId") Long orderId);

}

之后當(dāng)我們要使用時(shí),只需要注入OrderApiClient對(duì)象就可以了

雖然使用方便,但這并不是Feign最原始的使用方式,而是SpringCloud整合Feign之后的使用方式

Feign最開始是由Netflix開源的

后來SpringCloud就將Feign進(jìn)行了一層封裝,整合到自己的生態(tài),讓Feign使用起來更加簡(jiǎn)單

并同時(shí)也給它起了一個(gè)更高級(jí)的名字,OpenFeign

接下來文章表述有時(shí)可能并沒有嚴(yán)格區(qū)分Feign和OpenFeign的含義,你知道是這么個(gè)意思就行了。

Feign本身有自己的使用方式,也有類似Spring MVC相關(guān)的注解,如下所示:

public interface OrderApiClient {

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

}

OrderApiClient對(duì)象需要手動(dòng)通過Feign.builder()來創(chuàng)建

public class FeignDemo {

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

}

Feign的本質(zhì):動(dòng)態(tài)代理 + 七大核心組件

相信稍微了解Feign的小伙伴都知道,F(xiàn)eign底層其實(shí)是基于JDK動(dòng)態(tài)代理來的

所以Feign.builder()最終構(gòu)造的是一個(gè)代理對(duì)象

Feign在構(gòu)建動(dòng)態(tài)代理的時(shí)候,會(huì)去解析方法上的注解和參數(shù)

獲取Http請(qǐng)求需要用到基本參數(shù)以及和這些參數(shù)和方法參數(shù)的對(duì)應(yīng)關(guān)系

比如Http請(qǐng)求的url、請(qǐng)求體是方法中的第幾個(gè)參數(shù)、請(qǐng)求頭是方法中的第幾個(gè)參數(shù)等等

之后在構(gòu)建Http請(qǐng)求時(shí),就知道請(qǐng)求路徑以及方法的第幾個(gè)參數(shù)對(duì)應(yīng)是Http請(qǐng)求的哪部分?jǐn)?shù)據(jù)

當(dāng)調(diào)用動(dòng)態(tài)代理方法的時(shí)候,F(xiàn)eign就會(huì)將上述解析出來的Http請(qǐng)求基本參數(shù)和方法入?yún)⒔M裝成一個(gè)Http請(qǐng)求

然后發(fā)送Http請(qǐng)求,獲取響應(yīng),再根據(jù)響應(yīng)的內(nèi)容的類型將響應(yīng)體的內(nèi)容轉(zhuǎn)換成對(duì)應(yīng)的類型

這就是Feign的大致原理

圖片圖片

在整個(gè)Feign動(dòng)態(tài)代理生成和調(diào)用過程中,需要依靠Feign的一些核心組件來協(xié)調(diào)完成

如下圖所示是Feign的一些核心組件

這些核心組件可以通過Feign.builder()進(jìn)行替換

由于組件很多,這里我挑幾個(gè)重要的跟大家講一講

1、Contract

圖片圖片

前面在說Feign在構(gòu)建動(dòng)態(tài)代理的時(shí)候,會(huì)去解析方法上的注解和參數(shù),獲取Http請(qǐng)求需要用到基本參數(shù)

而這個(gè)Contract接口的作用就是用來干解析這件事的

Contract的默認(rèn)實(shí)現(xiàn)是解析Feign自己原生注解的

圖片圖片

解析時(shí),會(huì)為每個(gè)方法生成一個(gè)MethodMetadata對(duì)象

圖片圖片

MethodMetadata就封裝了Http請(qǐng)求需要用到基本參數(shù)以及這些參數(shù)和方法參數(shù)的對(duì)應(yīng)關(guān)系

SpringCloud在整合Feign的時(shí)候,為了讓Feign能夠識(shí)別Spring MVC的注解,所以就自己實(shí)現(xiàn)了Contract接口

2、Encoder

通過名字也可以看出來,這個(gè)其實(shí)用來編碼的

具體的作用就是將請(qǐng)求體對(duì)應(yīng)的方法參數(shù)序列化成字節(jié)數(shù)組

Feign默認(rèn)的Encoder實(shí)現(xiàn)只支持請(qǐng)求體對(duì)應(yīng)的方法參數(shù)類型為String和字節(jié)數(shù)組

圖片圖片

如果是其它類型,比如說請(qǐng)求體對(duì)應(yīng)的方法參數(shù)類型為AddOrderRequest.class類型,此時(shí)就無法對(duì)AddOrderRequest對(duì)象進(jìn)行序列化

這就導(dǎo)致默認(rèn)情況下,這個(gè)Encoder的實(shí)現(xiàn)很難用

于是乎,Spring就實(shí)現(xiàn)了Encoder接口

圖片圖片

可以將任意請(qǐng)求體對(duì)應(yīng)的方法參數(shù)類型對(duì)象序列化成字節(jié)數(shù)組

3、Decoder

Decoder的作用恰恰是跟Encoder相反

Encoder是將請(qǐng)求體對(duì)應(yīng)的方法參數(shù)序列化成字節(jié)數(shù)組

而Decoder其實(shí)就是將響應(yīng)體由字節(jié)流反序列化成方法返回值類型的對(duì)象

Decoder默認(rèn)情況下跟Encoder的默認(rèn)情況是一樣的,只支持反序列化成字節(jié)數(shù)組或者是String

所以,Spring也同樣實(shí)現(xiàn)了Decoder,擴(kuò)展它的功能

圖片圖片

可以將響應(yīng)體對(duì)應(yīng)的字節(jié)流反序列化成任意返回值類型對(duì)象

4、Client

圖片

從接口方法的參數(shù)和返回值其實(shí)可以看出,這其實(shí)就是動(dòng)態(tài)代理對(duì)象最終用來執(zhí)行Http請(qǐng)求的組件

默認(rèn)實(shí)現(xiàn)就是通過JDK提供的HttpURLConnection來的

除了這個(gè)默認(rèn)的,F(xiàn)eign還提供了基于HttpClient和OkHttp實(shí)現(xiàn)的

在項(xiàng)目中,要想替換默認(rèn)的實(shí)現(xiàn),只需要引入相應(yīng)的依賴,在構(gòu)建Feign.builder()時(shí)設(shè)置一下就行了

SpringCloud環(huán)境底下會(huì)根據(jù)引入的依賴自動(dòng)進(jìn)行設(shè)置

除了上述的三個(gè)實(shí)現(xiàn),最最重要的當(dāng)然是屬于它基于負(fù)載均衡的實(shí)現(xiàn)

如下是OpenFeign用來整合Ribbon的核心實(shí)現(xiàn)

圖片圖片

這個(gè)Client會(huì)根據(jù)服務(wù)名,從Ribbon中獲取一個(gè)服務(wù)實(shí)例的信息,也就是ip和端口

之后會(huì)通過ip和端口向服務(wù)實(shí)例發(fā)送Http請(qǐng)求

5、InvocationHandlerFactory

InvocationHandler我相信大家應(yīng)該都不陌生

對(duì)于JDK動(dòng)態(tài)代理來說,必須得實(shí)現(xiàn)InvocationHandler才能創(chuàng)建動(dòng)態(tài)代理

InvocationHandler的invoke方法實(shí)現(xiàn)就是動(dòng)態(tài)代理走的核心邏輯

而InvocationHandlerFactory其實(shí)就是創(chuàng)建InvocationHandler的工廠

所以,這里就可以猜到,通過InvocationHandlerFactory創(chuàng)建的InvocationHandler應(yīng)該就是Feign動(dòng)態(tài)代理執(zhí)行的核心邏輯

InvocationHandlerFactory默認(rèn)實(shí)現(xiàn)是下面這個(gè)

SpringCloud環(huán)境下默認(rèn)也是使用它的這個(gè)默認(rèn)實(shí)現(xiàn)

所以,我們直接去看看InvocationHandler的實(shí)現(xiàn)類FeignInvocationHandler

圖片圖片

從實(shí)現(xiàn)可以看出,除了Object類的一些方法,最終會(huì)調(diào)用方法對(duì)應(yīng)的MethodHandler的invoke方法

所以注意注意,這個(gè)MethodHandler就封裝了Feign執(zhí)行Http調(diào)用的核心邏輯,很重要,后面還會(huì)提到

圖片圖片

雖然說默認(rèn)情況下SpringCloud使用是默認(rèn)實(shí)現(xiàn),最終使用FeignInvocationHandler

但是當(dāng)其它框架整合SpringCloud生態(tài)的時(shí)候,為了適配OpenFeign,有時(shí)會(huì)自己實(shí)現(xiàn)InvocationHandler

比如常見的限流熔斷框架Hystrix和Sentinel都實(shí)現(xiàn)了自己的InvocationHandler

這樣就可以對(duì)MethodHandler執(zhí)行前后,也就是Http接口調(diào)用前后進(jìn)行限流降級(jí)等操作。

6、RequestInterceptor

圖片圖片

RequestInterceptor它其實(shí)是一個(gè)在發(fā)送請(qǐng)求前的一個(gè)攔截接口

通過這個(gè)接口,在發(fā)送Http請(qǐng)求之前再對(duì)Http請(qǐng)求的內(nèi)容進(jìn)行修改

比如我們可以設(shè)置一些接口需要的公共參數(shù),如鑒權(quán)token之類的

@Component
public class TokenRequestInterceptor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate template) {
        template.header("token", "token值");
    }

}

7、Retryer

這是一個(gè)重試的組件,默認(rèn)實(shí)現(xiàn)如下

默認(rèn)情況下,最大重試5次

在SpringCloud下,并沒有使用上面那個(gè)實(shí)現(xiàn),而使用的是下面這個(gè)實(shí)現(xiàn)

圖片圖片

所以,SpringCloud下默認(rèn)是不會(huì)進(jìn)行重試

小總結(jié)

這一節(jié)主要是介紹了7個(gè)Feign的核心組件以及Spring對(duì)應(yīng)的擴(kuò)展實(shí)現(xiàn)

為了方便你查看,我整理了如下表格

接口

作用

Feign默認(rèn)實(shí)現(xiàn)

Spring實(shí)現(xiàn)

Contract

解析方法注解和參數(shù),將Http請(qǐng)求參數(shù)和方法參數(shù)對(duì)應(yīng)

Contract.Default

SpringMvcContract

Encoder

將請(qǐng)求體對(duì)應(yīng)的方法參數(shù)序列化成字節(jié)數(shù)組

Encoder.Default

SpringEncoder

Decoder

將響應(yīng)體的字節(jié)流反序列化成方法返回值類型對(duì)象

Decoder.Default

SpringDecoder

Client

發(fā)送Http請(qǐng)求

Client.Default

LoadBalancerFeignClient

InvocationHandlerFactory

InvocationHandler工廠,動(dòng)態(tài)代理核心邏輯

InvocationHandlerFactory.Default

RequestInterceptor

在發(fā)送Http請(qǐng)求之前,再對(duì)Http請(qǐng)求的內(nèi)容進(jìn)行攔截修改

Retryer

重試組件

Retryer.Default

除了這些之外,還有一些其它組件這里就沒有說了

比如日志級(jí)別Logger.Level,日志輸出Logger,有興趣的可以自己查看

Feign核心運(yùn)行原理分析

上一節(jié)說了Feign核心組件,這一節(jié)我們來講一講Feign核心運(yùn)行原理,主要分為兩部分內(nèi)容:

  • 動(dòng)態(tài)代理生成原理
  • 一次Feign的Http調(diào)用執(zhí)行過程

1、動(dòng)態(tài)代理生成原理

這里我先把上面的Feign原始使用方式的Demo代碼再拿過來

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)獲取到動(dòng)態(tài)代理的

而上述代碼執(zhí)行邏輯如下所示:

圖片圖片

最終會(huì)調(diào)用ReflectiveFeign的newInstance方法來創(chuàng)建動(dòng)態(tài)代理對(duì)象

而ReflectiveFeign內(nèi)部設(shè)置了前面提到的一些核心組件

接下我們來看看newInstance方法

這個(gè)方法主要就干兩件事:

第一件事首先解析接口,構(gòu)建每個(gè)方法對(duì)應(yīng)的MethodHandler

MethodHandler在前面講InvocationHandlerFactory特地提醒過

動(dòng)態(tài)代理(FeignInvocationHandler)最終會(huì)調(diào)用MethodHandler來處理Feign的一次Http調(diào)用

在解析接口的時(shí)候,就會(huì)用到前面提到的Contract來解析方法參數(shù)和注解,生成MethodMetadata,這里我代碼我就不貼了

第二件事通過InvocationHandlerFactory創(chuàng)建InvocationHandler

然后再構(gòu)建出接口的動(dòng)態(tài)代理對(duì)象

ok,到這其實(shí)就走完了動(dòng)態(tài)代理的生成過程

所以動(dòng)態(tài)代理生成邏輯很簡(jiǎn)單,總共也沒幾行代碼,畫個(gè)圖來總結(jié)一下

圖片圖片

2、一次Feign的Http調(diào)用執(zhí)行過程

前面說了,調(diào)用接口動(dòng)態(tài)代理的方式時(shí),通過InvocationHandler(FeignInvocationHandler),最終交給MethodHandler的invoke方法來執(zhí)行

MethodHandler是一個(gè)接口,最終會(huì)走到它的實(shí)現(xiàn)類SynchronousMethodHandler的invoke方法實(shí)現(xiàn)

SynchronousMethodHandler中的屬性就是我們前面提到的一些組件

由于整個(gè)代碼調(diào)用執(zhí)行鏈路比較長,這里我就不截代碼了,有興趣的可以自己翻翻

不過這里我畫了一張圖,可以通過這張圖來大致分析整個(gè)Feign一次Http調(diào)用的過程

圖片圖片

  • 首先就是前面說的,進(jìn)入FeignInvocationHandler,找到方法對(duì)應(yīng)的SynchronousMethodHandler,調(diào)用invoke方法實(shí)現(xiàn)
  • 之后根據(jù)MethodMetadata和方法的入?yún)?,?gòu)造出一個(gè)RequestTemplate,RequestTemplate封裝了Http請(qǐng)求的參數(shù),在這個(gè)過程中,如果有請(qǐng)求體,那么會(huì)通過Encoder序列化
  • 然后調(diào)用RequestInterceptor,通過RequestInterceptor對(duì)RequestTemplate進(jìn)行攔截?cái)U(kuò)展,可以對(duì)請(qǐng)求數(shù)據(jù)再進(jìn)行修改
  • 再然后將RequestTemplate轉(zhuǎn)換成Request,Request其實(shí)跟RequestTemplate差不多,也是封裝了Http請(qǐng)求的參數(shù)
  • 接下來通過Client去根據(jù)Request中封裝的Http請(qǐng)求參數(shù),發(fā)送Http請(qǐng)求,得到響應(yīng)Response
  • 最后根據(jù)Decoder,將響應(yīng)體反序列化成方法返回值類型對(duì)象,返回

這就是Feign一次Http調(diào)用的執(zhí)行過程

如果有設(shè)置重試,那么也是在這個(gè)階段生效的

SpringCloud是如何整合Feign的?

SpringCloud在整合Feign的時(shí)候,主要是分為兩部分

  • 核心組件重新實(shí)現(xiàn),支持更多SpringCloud生態(tài)相關(guān)的功能
  • 將接口動(dòng)態(tài)代理對(duì)象注入到Spring容器中

第一部分核心組件重新實(shí)現(xiàn)前面已經(jīng)都說過了,這里就不再重復(fù)了

至于第二部分我們就來好好講一講,Spring是如何將接口動(dòng)態(tài)代理對(duì)象注入到Spring容器中的

1、將FeignClient接口注冊(cè)到Spring中

使用OpenFeign時(shí),必須加上@EnableFeignClients

這個(gè)注解就是OpenFeign的發(fā)動(dòng)機(jī)

圖片圖片

@EnableFeignClients最后通過@Import注解導(dǎo)入了一個(gè)FeignClientsRegistrar

圖片圖片

FeignClientsRegistrar實(shí)現(xiàn)了ImportBeanDefinitionRegistrar

所以最終Spring在啟動(dòng)的時(shí)候會(huì)調(diào)用registerBeanDefinitions方法實(shí)現(xiàn)

之所以會(huì)調(diào)用registerBeanDefinitions方法,是@Import注解的作用,不清楚的同學(xué)可以看一下扒一扒Bean注入到Spring的那些姿勢(shì),你會(huì)幾種?

圖片圖片

最終會(huì)走到registerFeignClients這個(gè)方法

這個(gè)方法雖然比較長,主要是干了下面這個(gè)2件事:

第一件事,掃描@EnableFeignClients所在類的包及其子包(如果有指定包就掃指定包),找出所有加了@FeignClient注解的接口,生成一堆BeanDefinition

這個(gè)BeanDefinition包含了這個(gè)接口的信息等信息

第二件事,將掃描到的這些接口注冊(cè)到Spring容器中

圖片圖片

在注冊(cè)的時(shí)候,并非直接注冊(cè)接口類型,而是FeignClientFactoryBean類型

圖片圖片

好了,到這整個(gè)@EnableFeignClients啟動(dòng)過程就結(jié)束了

雖然上面寫的很長,但是整個(gè)@EnableFeignClients其實(shí)也就只干了一件核心的事

掃描到所有的加了@FeignClient注解的接口

然后為每個(gè)接口生成一個(gè)Bean類型為FeignClientFactoryBean的BeanDefinition

最終注冊(cè)到Spring容器中

圖片圖片

2、FeignClientFactoryBean的秘密

上一節(jié)說到,每個(gè)接口都對(duì)應(yīng)一個(gè)class類型為FeignClientFactoryBean的BeanDefinition

圖片圖片

如上所示,F(xiàn)eignClientFactoryBean是一個(gè)FactoryBean

并且FeignClientFactoryBean的這些屬性,是在生成BeanDefinition的時(shí)候設(shè)置的

圖片圖片

并且這個(gè)type屬性就是代表的接口類型

由于實(shí)現(xiàn)了FactoryBean,所以Spring啟動(dòng)過程中,一定為會(huì)調(diào)用getObject方法獲取真正的Bean對(duì)象

FactoryBean的作用就不說了,不清楚的小伙伴還是可以看看扒一扒Bean注入到Spring的那些姿勢(shì),你會(huì)幾種?這篇文章

getObject最終會(huì)走到getTarget()方法

圖片圖片

從如上代碼其實(shí)可以看出來,最終還是會(huì)通過Feign.builder()來創(chuàng)建動(dòng)態(tài)代理對(duì)象

只不過不同的是,SpringCloud會(huì)替換Feign默認(rèn)的組件,改成自己實(shí)現(xiàn)的

總的來說,Spring是通過FactoryBean的這種方式,將Feign動(dòng)態(tài)代理對(duì)象添加到Spring容器中

OpenFeign的各種配置方式以及對(duì)應(yīng)優(yōu)先級(jí)

既然Feign核心組件可以替換,那么在SpringCloud環(huán)境下,我們?cè)撊绾稳ヅ渲米约旱慕M件呢?

不過在說配置之前,先說一下FeignClient配置隔離操作

在SpringCloud環(huán)境下,為了讓每個(gè)不同的FeignClient接口配置相互隔離

在應(yīng)用啟動(dòng)的時(shí)候,會(huì)為每個(gè)FeignClient接口創(chuàng)建一個(gè)Spring容器,接下來我就把這個(gè)容器稱為FeignClient容器

這些FeignClient的Spring容器有一個(gè)相同的父容器,那就是項(xiàng)目啟動(dòng)時(shí)創(chuàng)建的容器

圖片圖片

SpringCloud會(huì)給每個(gè)FeignClient容器添加一個(gè)默認(rèn)的配置類FeignClientsConfiguration配置類

圖片圖片

這個(gè)配置類就聲明了各種Feign的組件

圖片圖片

所以,默認(rèn)情況下,OpenFeign就使用這些配置的組件構(gòu)建代理對(duì)象

知道配置隔離之后,接下來看看具體的幾種方式配置以及它們之間的優(yōu)先級(jí)關(guān)系

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

舉個(gè)例子,比如我自己手動(dòng)聲明一個(gè)Contract對(duì)象,類型為MyContract

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

注意注意,這里FeignConfiguration我沒加@Configuration注解,原因后面再說

此時(shí)配置如下所示:

@EnableFeignClients(defaultConfiguration = FeignConfiguration.class)

之后這個(gè)配置類會(huì)被加到每個(gè)FeignClient容器中,所以這個(gè)配置是對(duì)所有的FeignClient生效

并且優(yōu)先級(jí)大于默認(rèn)配置的優(yōu)先級(jí)

比如這個(gè)例子就會(huì)使得FeignClient使用我聲明的MyContract,而不是FeignClientsConfiguration中聲明的SpringMvcContract

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

還以上面的FeignConfiguration配置類舉例,可以通過@FeignClient注解配置

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

此時(shí)這個(gè)配置類會(huì)被加到自己FeignClient容器中,注意是自己FeignClient容器

所以這種配置的作用范圍是自己的這個(gè)FeignClient

并且這種配置的優(yōu)先級(jí)是大于@EnableFeignClients注解配置的優(yōu)先級(jí)

3、在項(xiàng)目啟動(dòng)的容器中配置

前面提到,由于所有的FeignClient容器的父容器都是項(xiàng)目啟動(dòng)的容器

所以可以將配置放在這個(gè)項(xiàng)目啟動(dòng)的容器中

還以FeignConfiguration為例,加上@Configuration注解,讓項(xiàng)目啟動(dòng)的容器的掃描到就成功配置了

這種配置的優(yōu)先級(jí)大于前面提到的所有配置優(yōu)先級(jí)

并且是對(duì)所有的FeignClient生效

所以,這就是為什么使用注解配置時(shí)為什么配置類不能加@Configuration注解的原因,因?yàn)橐坏┍豁?xiàng)目啟動(dòng)的容器掃描到,這個(gè)配置就會(huì)作用于所有的FeignClient,并且優(yōu)先級(jí)是最高的,就會(huì)導(dǎo)致你其它的配置失效,當(dāng)然你也可以加@Configuration注解,但是一定不能被項(xiàng)目啟動(dòng)的容器掃到

4、配置文件

除了上面3種編碼方式配置,OpenFeign也是支持通過配置文件的方式進(jìn)行配置

并且也同時(shí)支持對(duì)所有FeignClient生效和對(duì)單獨(dú)某個(gè)FeignClient生效

對(duì)所有FeignClient生效配置:

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

對(duì)單獨(dú)某個(gè)FeignClient生效配置:

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

在默認(rèn)情況下,這種配置文件方式優(yōu)先級(jí)最高

但是如果你在配置文件中將配置項(xiàng)feign.client.default-to-properties設(shè)置成false的話,配置文件的方式優(yōu)先級(jí)就是最低了

feign:
  client:
    default-to-properties: false

小總結(jié)

這一節(jié),總共總結(jié)了4種配置OpenFeign的方式以及它們優(yōu)先級(jí)和作用范圍

畫張圖來總結(jié)一下

圖片圖片

如果你在具體使用的時(shí)候,還是遇到了一些優(yōu)先級(jí)的問題,可以debug這部分源碼,看看到底生效的是哪個(gè)配置


圖片圖片

圖片

責(zé)任編輯:武曉燕 來源: 三友的java日記
相關(guān)推薦

2023-10-16 22:07:20

Spring配置中心Bean

2024-01-02 22:47:47

Nacos注冊(cè)中心節(jié)點(diǎn)

2023-11-30 22:06:43

2024-07-08 23:03:13

2022-01-14 12:28:18

架構(gòu)OpenFeign遠(yuǎn)程

2010-08-18 10:13:55

IntentAndroid

2009-06-15 15:57:21

Spring工作原理

2020-12-04 06:37:19

HTTPS原理安全

2009-08-25 13:48:01

Java EE架構(gòu)企業(yè)級(jí)應(yīng)用

2025-01-10 09:47:43

blockSDKiOS

2024-02-26 00:00:00

Nginx服務(wù)器HTTP

2023-12-05 17:44:24

reactor網(wǎng)絡(luò)

2010-03-12 17:09:18

2010-01-27 17:38:58

Windows Emb

2019-12-12 10:56:00

微服務(wù)微服務(wù)架構(gòu)架構(gòu)

2023-06-07 15:25:19

Kafka版本日志

2025-02-08 08:10:00

2020-07-06 14:42:36

業(yè)務(wù)架構(gòu)IT架構(gòu)直播

2022-01-05 14:30:44

容器Linux網(wǎng)絡(luò)

2024-08-07 08:19:13

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)