SpringCloud 覆盖Feign默认值
Spring Cloud的Feign支持中的中心概念是指定客户的概念。每个虚拟客户端都是组件的一部分,这些组件可以一起工作以按需联系远程服务器,并且该组件的名称是您使用@FeignClient批注将其指定为应用程序开发人员的。Spring Cloud根据需要使用FeignClientsConfiguration为每个命名客户端创建一个新的合奏作为ApplicationContext。
其中包含feign.Decoder,feign.Encoder和feign.Contract。通过使用@FeignClient批注的contextId属性,可以覆盖该集合的名称。
Spring Cloud使您可以通过使用@FeignClient声明其他配置(在FeignClientsConfiguration之上)来完全控制假客户端。例:
@FeignClient(name = "stores", configuration = FooConfiguration.class) public interface StoreClient { //.. }
在这种情况下,客户端由FeignClientsConfiguration中已有的组件以及FooConfiguration中的任何组件组成(其中后者将覆盖前者)。
FooConfiguration不需要用@Configuration进行注释。但是,如果是的话,请注意将其从任何可能包含此配置的@ComponentScan中排除,因为它将成为feign.Decoder,feign.Encoder,feign.Contract等的默认来源,指定时。可以通过将其与任何@ComponentScan或@SpringBootApplication放在单独的,不重叠的包中来避免这种情况,也可以在@ComponentScan中将其明确排除在外。
现在不推荐使用
serviceId属性,而推荐使用name属性。
除了更改
ApplicationContext集合的名称之外,还使用@FeignClient批注的contextId属性,它会覆盖客户端名称的别名,并将其用作配置名称的一部分bean为该客户端创建的。
以前,使用
url属性不需要name属性。现在需要使用name。
name和url属性中支持占位符。
@FeignClient(name = "${feign.name}", url = "${feign.url}") public interface StoreClient { //.. }
Spring Cloud Netflix默认提供以下beans伪装(BeanType beanName:ClassName):
DecoderfeignDecoder:ResponseEntityDecoder(包装SpringDecoder)EncoderfeignEncoder:SpringEncoderLoggerfeignLogger:Slf4jLoggerContractfeignContract:SpringMvcContractFeign.BuilderfeignBuilder:HystrixFeign.BuilderClientfeignClient:如果启用了Ribbon,则它是LoadBalancerFeignClient,否则使用默认的伪装客户端。
可以通过分别将feign.okhttp.enabled或feign.httpclient.enabled设置为true并将其放在类路径中来使用OkHttpClient和ApacheHttpClient虚拟客户端。您可以自定义HTTP客户端,方法是在使用Apache时提供ClosableHttpClient的bean,在使用OK HTTP时提供OkHttpClient。
Spring Cloud Netflix 默认情况下不会为伪装提供以下beans,但仍会从应用程序上下文中查找以下类型的beans以创建伪装客户端:
Logger.LevelRetryerErrorDecoderRequest.OptionsCollection<RequestInterceptor>SetterFactory
创建其中一种类型的bean并将其放置在@FeignClient配置中(例如上述FooConfiguration),您可以覆盖上述的每个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也可以使用配置属性进行配置。
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中指定默认配置。不同之处在于此配置将适用于所有
伪客户端。
如果您希望使用配置属性来配置所有@FeignClient,则可以使用default虚拟名称创建配置属性。
application.yml
feign: client: config: default: connectTimeout: 5000 readTimeout: 5000 loggerLevel: basic
如果我们同时创建@Configuration bean和配置属性,则配置属性将获胜。它将覆盖@Configuration值。但是,如果要将优先级更改为@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
如果我们要创建多个具有相同名称或URL的伪装客户端,以便它们指向同一台服务器,但每个客户端使用不同的自定义配置,则必须使用@FeignClient的contextId属性,以避免这些配置beans的名称冲突。
@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class) public interface FooClient { //.. }
@FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class) public interface BarClient { //.. }