SpringCloud 覆蓋Feign默認(rèn)值

2023-11-24 14:20 更新

Spring Cloud的Feign支持中的中心概念是指定客戶的概念。每個(gè)虛擬客戶端都是組件的一部分,這些組件可以一起工作以按需聯(lián)系遠(yuǎn)程服務(wù)器,并且該組件的名稱是您使用@FeignClient批注將其指定為應(yīng)用程序開(kāi)發(fā)人員的。Spring Cloud根據(jù)需要使用FeignClientsConfiguration為每個(gè)命名客戶端創(chuàng)建一個(gè)新的合奏作為ApplicationContext。 其中包含feign.Decoder,feign.Encoderfeign.Contract。通過(guò)使用@FeignClient批注的contextId屬性,可以覆蓋該集合的名稱。

Spring Cloud使您可以通過(guò)使用@FeignClient聲明其他配置(在FeignClientsConfiguration之上)來(lái)完全控制假客戶端。例:

@FeignClient(name = "stores", configuration = FooConfiguration.class)
public interface StoreClient {
    //..
}

在這種情況下,客戶端由FeignClientsConfiguration中已有的組件以及FooConfiguration中的任何組件組成(其中后者將覆蓋前者)。

 FooConfiguration不需要用@Configuration進(jìn)行注釋。但是,如果是的話,請(qǐng)注意將其從任何可能包含此配置的 @ComponentScan中排除,因?yàn)樗鼘⒊蔀?/span>feign.Decoder,feign.Encoder, feign.Contract等的默認(rèn)來(lái)源,指定時(shí)。可以通過(guò)將其與任何@ComponentScan@SpringBootApplication 放在單獨(dú)的,不重疊的包中來(lái)避免這種情況,也可以在@ComponentScan中將其明確排除在外。

 現(xiàn)在不推薦使用serviceId屬性,而推薦使用name屬性。

 除了更改ApplicationContext集合的名稱之外,還使用@FeignClient批注的 contextId屬性,它會(huì)覆蓋客戶端名稱的別名,并將其用作配置名稱的一部分bean為該客戶端創(chuàng)建的。

 以前,使用url屬性不需要name屬性。現(xiàn)在需要使用 name。

nameurl屬性中支持占位符。

@FeignClient(name = "${feign.name}", url = "${feign.url}")
public interface StoreClient {
    //..
}

Spring Cloud Netflix默認(rèn)提供以下beans偽裝(BeanType beanName:ClassName):

  • Decoder feignDecoder:ResponseEntityDecoder(包裝SpringDecoder
  • Encoder feignEncoder:SpringEncoder
  • Logger feignLogger:Slf4jLogger
  • Contract feignContract:SpringMvcContract
  • Feign.Builder feignBuilder:HystrixFeign.Builder
  • Client feignClient:如果啟用了Ribbon,則它是LoadBalancerFeignClient,否則使用默認(rèn)的偽裝客戶端。

可以通過(guò)分別將feign.okhttp.enabledfeign.httpclient.enabled設(shè)置為true并將其放在類路徑中來(lái)使用OkHttpClient和ApacheHttpClient虛擬客戶端。您可以自定義HTTP客戶端,方法是在使用Apache時(shí)提供ClosableHttpClient的bean,在使用OK HTTP時(shí)提供OkHttpClient

Spring Cloud Netflix 默認(rèn)情況下不會(huì)為偽裝提供以下beans,但仍會(huì)從應(yīng)用程序上下文中查找以下類型的beans以創(chuàng)建偽裝客戶端:

  • Logger.Level
  • Retryer
  • ErrorDecoder
  • Request.Options
  • Collection<RequestInterceptor>
  • SetterFactory

創(chuàng)建其中一種類型的bean并將其放置在@FeignClient配置中(例如上述FooConfiguration),您可以覆蓋上述的每個(gè)beans。例:

@Configuration
public class FooConfiguration {
    @Bean
    public Contract feignContract() {
        return new feign.Contract.Default();
    }

    @Bean
    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
        return new BasicAuthRequestInterceptor("user", "password");
    }
}

這將SpringMvcContract替換為feign.Contract.Default,并將RequestInterceptor添加到RequestInterceptor的集合中。

@FeignClient也可以使用配置屬性進(jìn)行配置。

application.yml

feign:
  client:
    config:
      feignName:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: full
        errorDecoder: com.example.SimpleErrorDecoder
        retryer: com.example.SimpleRetryer
        requestInterceptors:
          - com.example.FooRequestInterceptor
          - com.example.BarRequestInterceptor
        decode404: false
        encoder: com.example.SimpleEncoder
        decoder: com.example.SimpleDecoder
        contract: com.example.SimpleContract

可以按照與上述類似的方式在@EnableFeignClients屬性defaultConfiguration中指定默認(rèn)配置。不同之處在于此配置將適用于所有 偽客戶端。

如果您希望使用配置屬性來(lái)配置所有@FeignClient,則可以使用default虛擬名稱創(chuàng)建配置屬性。

application.yml

feign:
  client:
    config:
      default:
        connectTimeout: 5000
        readTimeout: 5000
        loggerLevel: basic

如果我們同時(shí)創(chuàng)建@Configuration bean和配置屬性,則配置屬性將獲勝。它將覆蓋@Configuration值。但是,如果要將優(yōu)先級(jí)更改為@Configuration,可以將feign.client.default-to-properties更改為false。

 如果您需要在RequestInterceptor`s you will need to either set the thread isolation strategy for Hystrix to `SEMAPHORE中使用 ThreadLocal綁定變量,或者在Feign中禁用Hystrix。

application.yml

# To disable Hystrix in Feign
feign:
  hystrix:
    enabled: false

# To set thread isolation to SEMAPHORE
hystrix:
  command:
    default:
      execution:
        isolation:
          strategy: SEMAPHORE

如果我們要?jiǎng)?chuàng)建多個(gè)具有相同名稱或URL的偽裝客戶端,以便它們指向同一臺(tái)服務(wù)器,但每個(gè)客戶端使用不同的自定義配置,則必須使用@FeignClientcontextId屬性,以避免這些配置beans的名稱沖突。

@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class)
public interface FooClient {
    //..
}
@FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class)
public interface BarClient {
    //..
}
以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)