Spring Cloud OpenFeign
4.0.2
该项目通过自动配置和绑定到 Spring 环境和其他 Spring 编程模型,为 Spring Boot 应用程序提供 OpenFeign 集成。
声明式 REST 客户端:Feign
Feign 是一个声明式的 Web 服务客户端。它使编写 Web 服务客户端变得更加容易。要使用 Feign,请创建一个接口并对其进行注释。它具有可插入的注释支持,包括 Feign 注释和 JAX-RS 注释。 Feign 还支持可插入的编码器和解码器。 Spring Cloud 添加了对 Spring MVC 注释的支持,并支持使用在 Spring Web 中默认使用的相同 HttpMessageConverters
。 Spring Cloud 集成了 Eureka,Spring Cloud CircuitBreaker,以及 Spring Cloud LoadBalancer,在使用 Feign 时提供负载均衡的 http 客户端。
如何包含 Feign
要在您的项目中包含 Feign,请使用带有组 org.springframework.cloud
和工件 ID spring-cloud-starter-openfeign
的启动器。有关使用当前 Spring Cloud Release Train 设置构建系统的详细信息,请参阅 Spring Cloud Project 页面 。
示例 Spring Boot 应用程序
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
public interface StoreClient {
List<Store> getStores();
Page<Store> getStores(Pageable pageable);
Store update(; Long storeId, Store store)
void delete(; Long storeId)
}
在 @FeignClient
注解中,字符串值(上面的“stores”)是一个任意的客户端名称,用于创建 Spring Cloud LoadBalancer 客户端。您还可以使用 url
属性(绝对值或主机名)指定 URL。应用程序上下文中的 bean 名称是接口的完全限定名称。要指定您自己的别名值,您可以使用 @FeignClient
注释的 qualifiers
值。
上面的负载均衡器客户端将想要发现“stores”服务的物理地址。如果您的应用程序是 Eureka 客户端,那么它将解析 Eureka 服务注册表中的服务。如果不想使用 Eureka,可以使用 SimpleDiscoveryClient
在外部配置中配置服务器列表。
Spring Cloud OpenFeign 支持 Spring Cloud LoadBalancer 阻塞模式可用的所有特性。您可以在项目文档中阅读更多关于它们的信息。
要在 @Configuration
注释类上使用 @EnableFeignClients
注释,请确保指定客户端所在的位置,例如: @EnableFeignClients(basePackages = "com.example.clients")
或明确列出它们: @EnableFeignClients(clients = InventoryServiceFeignClient.class)
属性解析方式
在创建 Feign
客户端 bean 时,我们解析通过 @FeignClient
注释传递的值。从 4.x
开始,这些值正在急切地得到解决。对于大多数用例来说,这是一个很好的解决方案,它还允许 AOT 支持。
如果您需要延迟解析属性,请将 spring.cloud.openfeign.lazy-attributes-resolution
属性值设置为 true
。
对于 Spring Cloud Contract 测试集成,应该使用lazy-attributes-resolution
。
覆盖默认配置
Spring Cloud Feign 支持的一个核心概念是命名客户端。每个 Feign 客户端都是一组组件的一部分,这些组件协同工作以按需联系远程服务器,并且该组件有一个名称,您作为应用程序开发人员使用 @FeignClient
注释为其命名。 Spring Cloud 使用 FeignClientsConfiguration
为每个命名的客户端按需创建一个新的集成作为 ApplicationContext
。这包含(除其他外)一个 feign.Decoder
、一个 feign.Encoder
和一个 feign.Contract
。可以使用 @FeignClient
注释的 contextId
属性覆盖该集合的名称。
Spring Cloud 允许您通过使用 @FeignClient
声明附加配置(在 FeignClientsConfiguration
之上)来完全控制 feign 客户端。
例如:
public interface StoreClient {
//..
}
在这种情况下,客户端由 FeignClientsConfiguration
中已有的组件和 FooConfiguration
中的任何组件组成(后者将覆盖前者)。
FooConfiguration
不需要用 @Configuration
注释。但是,如果是,则注意将其从任何 @ComponentScan
中排除,否则将包含此配置,因为在指定时它将成为 feign.Decoder
、 feign.Encoder
、 feign.Contract
等的默认源。这可以通过将它放在与任何 @ComponentScan
或 @SpringBootApplication
分开的、不重叠的包中来避免,或者它可以在 @ComponentScan
中明确排除。
使用 @FeignClient
注释的 contextId
属性除了更改 ApplicationContext
集合的名称之外,它将覆盖客户端名称的别名,并将用作为此创建的配置bean 的名称的一部分客户。
以前,使用 url
属性不需要 name
属性。现在需要使用 name
。
name
和 url
属性支持占位符。
public interface StoreClient {
//..
}
Spring Cloud OpenFeign默认为feign提供了以下bean( BeanType
beanName: ClassName
):
Decoder
feignDecoder:ResponseEntityDecoder
(包装了一个SpringDecoder
)Encoder
feignEncoder:SpringEncoder
Logger
feignLogger:Slf4jLogger
MicrometerObservationCapability
micrometerObservationCapability:如果feign-micrometer
在类路径上并且ObservationRegistry
可用MicrometerCapability
micrometerCapability:如果feign-micrometer
在类路径上,则MeterRegistry
可用,ObservationRegistry
不可用CachingCapability
cachingCapability:如果使用了@EnableCaching
注解。可以通过spring.cloud.openfeign.cache.enabled
禁用。Contract
feignContract:SpringMvcContract
Feign.Builder
feignBuilder:FeignCircuitBreaker.Builder
Client
feignClient:如果类路径上有Spring Cloud LoadBalancer,则使用FeignBlockingLoadBalancerClient
。如果它们都不在类路径中,则使用默认的feignClient。
spring-cloud-starter-openfeign
支持 spring-cloud-starter-loadbalancer
。但是,作为可选依赖项,如果要使用它,您需要确保它已添加到您的项目中。
OkHttpClient 和 Apache HttpClient 5 Feign 客户端可以通过分别将 spring.cloud.openfeign.okhttp.enabled
或 spring.cloud.openfeign.httpclient.hc5.enabled
设置为 true
并将它们放在类路径中来使用。在使用 Apache HC5 时,您可以通过提供 org.apache.hc.client5.http.impl.classic.CloseableHttpClient
的 bean 来自定义使用的 HTTP 客户端。
您可以通过在 spring.cloud.openfeign.httpclient.xxx
属性中设置值来进一步自定义 http 客户端。仅以 httpclient
为前缀的将适用于所有客户端,以 httpclient.hc5
为前缀的适用于 Apache HttpClient 5,以 httpclient.okhttp
为前缀的适用于 OkHttpClient。您可以在附录中找到可以自定义的属性的完整列表。
从 Spring Cloud OpenFeign 4 开始,不再支持 Feign Apache HttpClient 4。我们建议改用 Apache HttpClient 5。
Spring Cloud OpenFeign默认不为feign提供以下bean,但还是会从application context中查找这些类型的bean来创建feign client:
Logger.Level
Retryer
ErrorDecoder
Request.Options
Collection<RequestInterceptor>
SetterFactory
QueryMapEncoder
Capability
(默认提供MicrometerObservationCapability
和CachingCapability
)
默认情况下会创建 Retryer
类型的 Retryer.NEVER_RETRY
bean,这将禁用重试。请注意,此重试行为与 Feign 默认行为不同,Feign 默认行为会自动重试 IOExceptions,将它们视为暂时性网络相关异常,以及从 ErrorDecoder 抛出的任何 RetryableException。
创建其中一种类型的 bean 并将其放置在 @FeignClient
配置中(例如上面的 FooConfiguration
)允许您覆盖所描述的每个 bean。
例如:
public class FooConfiguration {
public Contract feignContract() {
return new feign.Contract.Default();
}
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("user", "password");
}
}
这会将 SpringMvcContract
替换为 feign.Contract.Default
并将 RequestInterceptor
添加到 RequestInterceptor
的集合中。
@FeignClient
也可以使用配置属性进行配置。spring:
cloud:
openfeign:
client:
config:
feignName:
url: http://remote-service.com
connectTimeout: 5000
readTimeout: 5000
loggerLevel: full
errorDecoder: com.example.SimpleErrorDecoder
retryer: com.example.SimpleRetryer
defaultQueryParameters:
query: queryValue
defaultRequestHeaders:
header: headerValue
requestInterceptors:
- com.example.FooRequestInterceptor
- com.example.BarRequestInterceptor
responseInterceptor: com.example.BazResponseInterceptor
dismiss404: false
encoder: com.example.SimpleEncoder
decoder: com.example.SimpleDecoder
contract: com.example.SimpleContract
capabilities:
- com.example.FooCapability
- com.example.BarCapability
queryMapEncoder: com.example.SimpleQueryMapEncoder
micrometer.enabled: false
此示例中的 feignName
指的是 @FeignClient
value
,它也是 @FeginClient
name
和 @FeignClient
contextId
的别名。在负载均衡的场景中,它还对应于将用于检索实例的服务器应用程序的 serviceId
。
可以按照与上述类似的方式在 @EnableFeignClients
属性 defaultConfiguration
中指定默认配置。不同之处在于,此配置将适用于所有 feign 客户端。
如果您更喜欢使用配置属性来配置所有 @FeignClient
,则可以使用 default
feign 名称创建配置属性。
您可以使用 spring.cloud.openfeign.client.config.feignName.defaultQueryParameters
和 spring.cloud.openfeign.client.config.feignName.defaultRequestHeaders
来指定将与名为 feignName
的客户端的每个请求一起发送的查询参数和标头。spring:
cloud:
openfeign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 5000
loggerLevel: basic
如果我们同时创建 @Configuration
bean 和配置属性,配置属性将获胜。它将覆盖 @Configuration
值。但是如果你想把优先级改成 @Configuration
,你可以把 spring.cloud.openfeign.client.default-to-properties
改成 false
。
如果我们想创建多个具有相同名称或 url 的feignClient,以便它们指向同一台服务器但每个都有不同的自定义配置,那么我们必须使用 @FeignClient
的 contextId
属性以避免名称冲突这些配置bean。
public interface FooClient {
//..
}
public interface BarClient {
//..
}
也可以将 FeignClient 配置为不从父上下文继承 bean。您可以通过覆盖 FeignClientConfigurer
bean 中的 inheritParentConfiguration()
以返回 false
来做到这一点:
public class CustomConfiguration{
public FeignClientConfigurer feignClientConfigurer() {
return new FeignClientConfigurer() {
public boolean inheritParentConfiguration() {
return false;
}
};
}
}
默认情况下,Feign 客户端不对斜杠 /
字符进行编码。您可以通过将 spring.cloud.openfeign.client.decodeSlash
的值设置为 false
来更改此行为。
SpringEncoder
配置
在我们提供的 SpringEncoder
中,我们为二进制内容类型设置了 null
字符集,为所有其他类型设置了 UTF-8
。
您可以通过将 spring.cloud.openfeign.encoder.charset-from-content-type
的值设置为 true
来修改此行为以从 Content-Type
标头字符集派生字符集。
Timeout 处理
我们可以在默认客户端和指定客户端上配置超时。 OpenFeign 使用两个超时参数:
connectTimeout
防止由于服务器处理时间长而阻塞调用者。readTimeout
从建立连接开始应用,当返回响应时间过长时触发。
如果服务器未运行或不可用,则数据包会导致连接被拒绝。通信以错误消息或回退结束。如果设置得非常低,这可能会在 connectTimeout
之前发生。执行查找和接收此类数据包所花费的时间会导致此延迟的很大一部分。它可能会根据涉及 DNS 查找的远程主机而发生变化。
手动创建 Feign Clients
在某些情况下,可能需要以使用上述方法无法实现的方式自定义 Feign 客户端。在这种情况下,您可以使用 Feign Builder API 创建客户端。下面是一个示例,它创建了两个具有相同接口的 Feign 客户端,但为每个客户端配置了一个单独的请求拦截器。
class FooController {
private FooClient fooClient;
private FooClient adminClient;
public FooController(Client client, Encoder encoder, Decoder decoder, Contract contract, MicrometerObservationCapability micrometerObservationCapability) {
this.fooClient = Feign.builder().client(client)
.encoder(encoder)
.decoder(decoder)
.contract(contract)
.addCapability(micrometerObservationCapability)
.requestInterceptor(new BasicAuthRequestInterceptor("user", "user"))
.target(FooClient.class, "https://PROD-SVC");
this.adminClient = Feign.builder().client(client)
.encoder(encoder)
.decoder(decoder)
.contract(contract)
.addCapability(micrometerObservationCapability)
.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
.target(FooClient.class, "https://PROD-SVC");
}
}
上面例子中的 FeignClientsConfiguration.class
是Spring Cloud OpenFeign提供的默认配置。
PROD-SVC
是客户端将向其发出请求的服务的名称。
Feign Contract
对象定义了哪些注释和值在接口上有效。自动装配的 Contract
bean 提供对 SpringMVC 注释的支持,而不是默认的 Feign 本机注释。
您还可以使用Builder
来配置FeignClient,使其不从父上下文继承bean。你可以通过重写Builder
上的inheritParentContext(false)
来实现这一点。
支持 Feign Spring Cloud CircuitBreaker
如果 Spring Cloud CircuitBreaker 在类路径上并且 spring.cloud.openfeign.circuitbreaker.enabled=true
,Feign 将使用断路器包装所有方法。
要在每个客户端的基础上禁用 Spring Cloud CircuitBreaker 支持,请创建一个带有“原型”范围的香草 Feign.Builder
。
例如:
public class FooConfiguration {
public Feign.Builder feignBuilder() {
return Feign.builder();
}
}
断路器名称遵循此模式 <feignClientClassName>#<calledMethod>(<parameterTypes>)
。当使用 FooClient
接口调用 @FeignClient
并且被调用的没有参数的接口方法是 bar
时,断路器名称将是 FooClient#bar()
。
自 2020.0.2 起,断路器名称模式已从 <feignClientName>_<calledMethod>
更改。使用 2020.0.4 引入的 CircuitBreakerNameResolver
,断路器名称可以保留旧模式。
提供一个 CircuitBreakerNameResolver
的 bean,你可以更改断路器名称模式。
public class FooConfiguration {
public CircuitBreakerNameResolver circuitBreakerNameResolver() {
return (String feignClientName, Target<?> target, Method method) -> feignClientName + "_" + method.getName();
}
}
要启用 Spring Cloud CircuitBreaker 组,请将 spring.cloud.openfeign.circuitbreaker.group.enabled
属性设置为 true
(默认为 false
)。
通过配置属性配置 CircuitBreakers
您可以通过配置属性配置断路器。
例如,如果你有这个 Feign 客户端
public interface DemoClient {
String getDemo();
}
你可以像如下这样通过配置项进行配置spring:
cloud:
openfeign
circuitbreaker:
enabled: true
alphanumeric-ids:
enabled: true
resilience4j:
circuitbreaker:
instances:
DemoClientgetDemo:
minimumNumberOfCalls: 69
timelimiter:
instances:
DemoClientgetDemo:
timeoutDuration: 10s
如果你想切换回 Spring Cloud 2022.0.0 之前使用的断路器名称,你可以将 spring.cloud.openfeign.circuitbreaker.alphanumeric-ids.enabled
设置为 false
。
Feign Spring Cloud CircuitBreaker Fallbacks
Spring Cloud CircuitBreaker支持fallback(回退)的概念:当Circuit启用或出现错误时执行的默认代码路径。要为给定的 @FeignClient
启用fallback功能的话,需要将 fallback
属性设置为实现fallback的类名。您还需要将您的实现声明为 Spring bean。
protected interface TestClient {
Hello getHello();
String getException();
}
static class Fallback implements TestClient {
public Hello getHello() {
throw new NoFallbackAvailableException("Boom!", new RuntimeException());
}
public String getException() {
return "Fixed response";
}
}
如果需要操作导致fallback的cause,可以使用 @FeignClient
中的 fallbackFactory
属性。
protected interface TestClientWithFactory {
Hello getHello();
String getException();
}
static class TestFallbackFactory implements FallbackFactory<FallbackWithFactory> {
public FallbackWithFactory create(Throwable cause) {
return new FallbackWithFactory();
}
}
static class FallbackWithFactory implements TestClientWithFactory {
public Hello getHello() {
throw new NoFallbackAvailableException("Boom!", new RuntimeException());
}
public String getException() {
return "Fixed response";
}
}
Feign and @Primary
将 Feign 与 Spring Cloud CircuitBreaker fallbacks 一起使用时, ApplicationContext
中有多个相同类型的 bean。这将导致 @Autowired
无法工作,因为不完全是一个 bean,或者一个被标记为主要的。为了解决这个问题,Spring Cloud OpenFeign 将所有 Feign 实例标记为 @Primary
,因此 Spring Framework 将知道要注入哪个 bean。在某些情况下,这可能是不可取的。要关闭此行为,请将 @FeignClient
的 primary
属性设置为 false。
public interface HelloClient {
// methods here
}
Feign 支持继承
Feign 通过单继承接口支持样板 API。这允许将常见操作分组到方便的基本接口中。public interface UserService {
User getUser(long id);
}
public class UserResource implements UserService {
}package project.user;
public interface UserClient extends UserService {
}
@FeignClient
接口不应在服务器和客户端之间共享,并且不再支持在类级别上使用 @RequestMapping
注释 @FeignClient
接口。
Feign 压缩请求/响应
您可以考虑为您的 Feign 请求启用请求或响应 GZIP 压缩。您可以通过启用以下属性之一来执行此操作:spring.cloud.openfeign.compression.request.enabled=true
spring.cloud.openfeign.compression.response.enabled=true
Feign 请求压缩为您提供类似于您为 Web 服务器设置的设置:spring.cloud.openfeign.compression.request.enabled=true
spring.cloud.openfeign.compression.request.mime-types=text/xml,application/xml,application/json
spring.cloud.openfeign.compression.request.min-request-size=2048
这些属性允许您选择压缩媒体类型和最小请求阈值长度。
由于 OkHttpClient 使用 “transparent” 压缩,如果 content-encoding
或 accept-encoding
标头存在则禁用,因此当类路径上存在 feign.okhttp.OkHttpClient
且 spring.cloud.openfeign.okhttp.enabled
设置为 true
时,我们不启用压缩。
Feign logging
为每个创建的 Feign 客户端创建一个记录器。默认情况下,logger的名称使用的是创建 Feign 客户端的接口的完整类名。 Feign logging 只响应 DEBUG
级别。logging.level.project.user.UserClient: DEBUG
您可以为每个客户端配置的 Logger.Level
对象告诉 Feign 要记录多少。选项是:
NONE
,无日志记录(默认)。BASIC
,只记录请求方法和URL以及响应状态码和执行时间。HEADERS
,记录基本信息以及请求和响应标头。FULL
,记录请求和响应的标头、正文和元数据。
例如,以下内容会将 Logger.Level
设置为 FULL
:
public class FooConfiguration {
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
支持 Feign Capability
The Feign capabilities expose core Feign components so that these components can be modified. For example, the capabilities can take the Client
, decorate it, and give the decorated instance back to Feign. The support for Micrometer is a good real-life example for this. See Micrometer Support.
Feign Capability 公开核心Feign组件,以便可以修改这些组件。例如,Capability 可以接受 Client
,装饰它,并将装饰后的实例返回给Feign。对Micrometer的支持就是一个很好的现实例子。参见Micrometer Support。
创建一个或多个 Capability
beans 并将它们放置在 @FeignClient
配置中允许您注册它们并修改相关客户端的行为。
public class FooConfiguration {
Capability customCapability() {
return new CustomCapability();
}
}
支持 Micrometer
如果满足以下所有条件,则会创建并注册一个 MicrometerObservationCapability
bean,以便 Micrometer 可以观察到您的 Feign 客户端:
feign-micrometer
在类路径上ObservationRegistry
bean 可用- feign micrometer 属性设置为
true
(默认)spring.cloud.openfeign.micrometer.enabled=true
(针对所有客户端)spring.cloud.openfeign.client.config.feignName.micrometer.enabled=true
(针对单个客户端)
如果您的应用程序已经使用了 Micrometer,启用此功能就像将 feign-micrometer
放入您的类路径一样简单。
您还可以通过以下任一方式禁用该功能:
- 从你的类路径中排除
feign-micrometer
- 将假测微计属性之一设置为
false
spring.cloud.openfeign.micrometer.enabled=false
spring.cloud.openfeign.client.config.feignName.micrometer.enabled=false
spring.cloud.openfeign.micrometer.enabled=false
禁用对所有 Feign 客户端的 Micrometer 支持,无论客户端级别标志的值如何: spring.cloud.openfeign.client.config.feignName.micrometer.enabled
。如果要为每个客户端启用或禁用 Micrometer 支持,请不要设置 spring.cloud.openfeign.micrometer.enabled
并使用 spring.cloud.openfeign.client.config.feignName.micrometer.enabled
。
您还可以通过注册自己的 bean 来自定义 MicrometerObservationCapability
:
public class FooConfiguration {
public MicrometerObservationCapability micrometerObservationCapability(ObservationRegistry registry) {
return new MicrometerObservationCapability(registry);
}
}
仍然可以将 MicrometerCapability
与 Feign(仅支持指标)一起使用,您需要禁用 Micrometer 支持( spring.cloud.openfeign.micrometer.enabled=false
)并创建一个 MicrometerCapability
bean:
public class FooConfiguration {
public MicrometerCapability micrometerCapability(MeterRegistry meterRegistry) {
return new MicrometerCapability(meterRegistry);
}
}
Feign Caching
如果使用 @EnableCaching
注解,就会创建并注册一个 CachingCapability
bean,这样你的Feign客户端就可以在它的接口上识别 @Cache*
注解:public interface DemoClient {
String demoEndpoint(String keyParam, ; String filterParam)
}
您还可以通过属性 spring.cloud.openfeign.cache.enabled=false
禁用该功能。
支持 Feign @QueryMap
Spring Cloud OpenFeign提供了一个等价的 @SpringQueryMap
注解,用于将POJO或Map参数注解为查询参数映射。
例如, Params
类定义参数 param1
和 param2
:// Params.java
public class Params {
private String param1;
private String param2;
// [Getters and setters omitted for brevity]
}
下面的 feign 客户端通过使用 @SpringQueryMap
注解来使用 Params
类:
public interface DemoTemplate {
String demoEndpoint(; Params params)
}
如果您需要更多地控制生成的查询参数映射,您可以实现自定义 QueryMapEncoder
bean。
支持 HATEOAS
Spring 提供了一些 API 来创建遵循 HATEOAS 原则、Spring Hateoas 和 Spring Data REST 的 REST 表示。
如果您的项目使用 org.springframework.boot:spring-boot-starter-hateoas
starter 或 org.springframework.boot:spring-boot-starter-data-rest
starter,则默认启用 Feign HATEOAS 支持。
启用 HATEOAS 支持后,允许 Feign 客户端序列化和反序列化 HATEOAS 表示模型:EntityModel](https://docs.spring.io/spring-hateoas/docs/1.0.0.M1/apidocs/org/springframework/hateoas/EntityModel.html), CollectionModel and PagedModel。
public interface DemoTemplate {
CollectionModel<Store> getStores();
}
支持 Spring @MatrixVariable
Spring Cloud OpenFeign 提供对 Spring @MatrixVariable
注解的支持。
如果将映射作为方法参数传递,则通过使用 =
连接映射中的键值对来创建 @MatrixVariable
路径段。
如果传递了不同的对象,则 @MatrixVariable
注释(如果已定义)中提供的 name
或带注释的变量名称使用 =
与提供的方法参数连接。
IMPORTANT
即使在服务器端,Spring 不要求用户将路径段占位符命名为与矩阵变量名称相同,因为它在客户端太模糊了,Spring Cloud OpenFeign 要求您添加一个路径段占位符与
@MatrixVariable
注释(如果已定义)中提供的name
或带注释的变量名称相匹配的名称。
For example:
Map<String, List<String>> getObjects(; Map<String, List<String>> matrixVars)
请注意,变量名和路径段占位符都称为 matrixVars
。
public interface DemoTemplate {
CollectionModel<Store> getStores();
}
支持 Feign CollectionFormat
我们通过提供 @CollectionFormat
注释来支持 feign.CollectionFormat
。您可以通过传递所需的 feign.CollectionFormat
作为注释值来注释 Feign 客户端方法(或影响所有方法的整个类)。
在下面的示例中,使用 CSV
格式而不是默认的 EXPLODED
来处理方法。
protected interface DemoFeignClient {
ResponseEntity performRequest(String test);
}
支持 Reactive
由于 OpenFeign 项目目前不支持响应式客户端,例如 Spring WebClient,Spring Cloud OpenFeign 也不支持。一旦核心项目可用,我们将在此处添加对它的支持。
在此之前,我们建议使用 feign-reactive 来支持 Spring WebClient。
启动初始化报错
根据您使用 Feign 客户端的方式,您可能会在启动应用程序时看到初始化错误。要解决此问题,您可以在自动装配客户端时使用 ObjectProvider
。
ObjectProvider<TestFeignClient> testFeignClient;
支持 Spring Data
如果 Jackson Databind 和 Spring Data Commons 在类路径中, org.springframework.data.domain.Page
和 org.springframework.data.domain.Sort
的转换器将被自动添加。
禁用此行为spring.cloud.openfeign.autoconfiguration.jackson.enabled=false
更多细节参考 org.springframework.cloud.openfeign.FeignAutoConfiguration.FeignJacksonConfiguration
。
支持 Spring @RefreshScope
如果启用了 Feign 客户端刷新,则创建每个 Feign 客户端时:
feign.Request.Options
作为刷新范围的 bean。这意味着可以针对任何 Feign 客户端实例刷新诸如connectTimeout
和readTimeout
之类的属性。- 包裹在
org.springframework.cloud.openfeign.RefreshableUrl
下的 url。这意味着 Feign 客户端的 URL,如果使用spring.cloud.openfeign.client.config.{feignName}.url
属性定义,则可以针对任何 Feign 客户端实例进行刷新。
您可以通过 POST /actuator/refresh
刷新这些属性。
默认情况下,Feign 客户端中的刷新功能是禁用的。使用以下属性启用刷新功能:spring.cloud.openfeign.client.refresh-enabled=true
不要使用 @RefreshScope
注释来注释 @FeignClient
接口。
支持 OAuth2
可以通过设置以下标志启用 OAuth2 支持:spring.cloud.openfeign.oauth2.enabled=true
当标志设置为 true 并且存在 oauth2 客户端上下文资源详细信息时,将创建 OAuth2AccessTokenInterceptor
类的 bean。在每个请求之前,拦截器解析所需的访问令牌并将其作为标头包含在内。 OAuth2AccessTokenInterceptor
使用 OAuth2AuthorizedClientManager
获取持有 OAuth2AccessToken
的 OAuth2AuthorizedClient
。如果用户使用 spring.cloud.openfeign.oauth2.clientRegistrationId
属性指定了 OAuth2 clientRegistrationId
,它将用于检索令牌。如果未检索到令牌或未指定 clientRegistrationId
,则将使用从 url
主机段检索到的 serviceId
。
TIP
使用
serviceId
作为 OAuth2 客户端 registrationId 对于负载均衡的 Feign 客户端来说很方便。对于非负载均衡的,基于属性的clientRegistrationId
是一种合适的方法。TIP
如果你不想使用
OAuth2AuthorizedClientManager
的默认设置,你可以在你的配置中实例化一个这种类型的 bean。
Transform the load-balanced HTTP request
您可以使用选定的 ServiceInstance
来转换负载均衡的 HTTP 请求。
对于 Request
,你需要实现和定义 LoadBalancerFeignRequestTransformer
,如下:
public LoadBalancerFeignRequestTransformer transformer() {
return new LoadBalancerFeignRequestTransformer() {
public Request transformRequest(Request request, ServiceInstance instance) {
Map<String, Collection<String>> headers = new HashMap<>(request.headers());
headers.put("X-ServiceId", Collections.singletonList(instance.getServiceId()));
headers.put("X-InstanceId", Collections.singletonList(instance.getInstanceId()));
return Request.create(request.httpMethod(), request.url(), headers, request.body(), request.charset(), request.requestTemplate());
}
};
}
如果定义了多个转换器,它们将按照定义 bean 的顺序应用。或者,您可以使用 LoadBalancerFeignRequestTransformer.DEFAULT_ORDER
来指定顺序。
支持 X-Forwarded Headers
可以通过设置以下标志来启用 X-Forwarded-Host
和 X-Forwarded-Proto
支持:spring.cloud.loadbalancer.x-forwarded.enabled=true
支持多种向Feign Client提供URL的方式
您可以通过以下任何一种方式向 Feign 客户端提供 URL:
Case | Example | Details |
---|---|---|
该 URL 在 @FeignClient 注释中提供。 | @FeignClient(name="testClient", url="http://localhost:8081") | URL 从注释的 url 属性解析,没有负载平衡。 |
该 URL 在 @FeignClient 注释和配置属性中提供。 | @FeignClient(name="testClient", url="http://localhost:8081") 和 application.yml 中定义的属性为 spring.cloud.openfeign.client.config.testClient.url=http://localhost:8081 | URL 从注释的 url 属性解析,没有负载平衡。配置属性中提供的 URL 保持未使用状态。 |
该 URL 未在 @FeignClient 注释中提供,但在配置属性中提供。 | @FeignClient(name="testClient") 和 application.yml 中定义的属性为 spring.cloud.openfeign.client.config.testClient.url=http://localhost:8081 | URL 从配置属性解析,没有负载平衡。如果是 spring.cloud.openfeign.client.refresh-enabled=true ,那么可以按照 Spring RefreshScope Support 中的描述刷新配置属性中定义的 URL。 |
@FeignClient 注释和配置属性中均未提供该 URL。 | @FeignClient(name="testClient") | URL 是从注解的 name 属性中解析出来的,具有负载均衡。 |
支持 AOT and Native Image
Spring Cloud OpenFeign 支持 Spring AOT 转换和原生图像,但是,仅在禁用刷新模式、禁用 Feign 客户端刷新(默认设置)和禁用 lazy @FeignClient
attribute resolution(默认设置)的情况下。
如果要在 AOT 或原生图像模式下运行 Spring Cloud OpenFeign 客户端,请确保将 spring.cloud.refresh.enabled
设置为 false
。
如果要在 AOT 或原生图像模式下运行 Spring Cloud OpenFeign 客户端,请确保 spring.cloud.openfeign.client.refresh-enabled
未设置为 true
。
如果要在 AOT 或原生图像模式下运行 Spring Cloud OpenFeign 客户端,请确保 spring.cloud.openfeign.lazy-attributes-resolution
未设置为 true
。
但是,如果您通过属性设置 url
值,则可以通过使用 -Dspring.cloud.openfeign.client.config.[clientId].url=[url]
标志运行图像来覆盖 @FeignClient
url
值。为了启用覆盖, url
值还必须在构建期间通过属性设置,而不是 @FeignClient
属性。
配置属性
要查看所有 Spring Cloud OpenFeign 相关配置属性的列表,请查看附录页面。