Spring Cloud OpenFeign Features
Declarative REST Client: Feign
Feign是一种声明性 Web 服务客户端,它让编写 Web 服务客户端变得更加容易。要使用 Feign,请创建一个界面并对其进行注释。它具有可插拔的注释支持,包括 Feign 注释和 JAX-RS 注释。Feign 还支持可插拔的编码器和解码器。Spring Cloud 为 Spring MVC 注释增加了支持,并用于 Spring Web 中默认使用的相同 HttpMessageConverters
。当使用 Feign 时,Spring Cloud 集成了 Eureka、Spring Cloud CircuitBreaker 以及 Spring Cloud LoadBalancer,以提供负载均衡的 http 客户端。
How to Include Feign
要将 Feign 包含在你的项目中,请使用组 `org.springframework.cloud`和构件 ID `spring-cloud-starter-openfeign`的启动器。有关使用当前 Spring Cloud 发布版本来设置你的构建系统的详细信息,请参阅 Spring Cloud Project page。
Spring Boot 应用示例
@SpringBootApplication
@EnableFeignClients
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
@FeignClient("stores")
public interface StoreClient {
@RequestMapping(method = RequestMethod.GET, value = "/stores")
List<Store> getStores();
@GetMapping("/stores")
Page<Store> getStores(Pageable pageable);
@PostMapping(value = "/stores/{storeId}", consumes = "application/json")
Store update(@PathVariable("storeId") Long storeId, Store store);
@DeleteMapping("/stores/{storeId:\\d+}")
void delete(@PathVariable Long storeId);
}
在 `@FeignClient`注释中,字符串值(上方的“stores”)是一个任意客户端名称,用于创建一个 Spring Cloud LoadBalancer client。你还可以使用 `url`属性(绝对值或仅主机名)指定一个 URL。应用程序上下文中 Bean 的名称是接口的全限定名称。为了指定你自己的别名字符串,你可以使用 `@FeignClient`注释的 `qualifiers`值。
上述负载均衡器客户端需要发现“stores”服务的物理地址。如果你的应用程序是 Eureka 客户端,那么它将在 Eureka 服务注册表中解析服务。如果你不想使用 Eureka,则可以使用 SimpleDiscoveryClient
在外部配置中配置服务器列表。
Spring Cloud OpenFeign 支持 Spring Cloud LoadBalancer 的阻塞模式中可用的所有功能。你可以在 project documentation中阅读更多相关信息。
要使用 |
Overriding Feign Defaults
Spring Cloud 对 Feign 支持中的一个核心概念是已命名客户端。每个 feign 客户端是一个组件集的一部分,这些组件共同在按需联系远程服务器时协同工作,并且该组件集有一个名称,您会使用 @FeignClient
标注将其作为应用程序开发人员提供。Spring Cloud 使用 FeignClientsConfiguration
为每个已命名客户端按需创建一个 ApplicationContext
作为 Ensemble
。这(除其他内容外)包含一个 feign.Decoder
、一个 feign.Encoder
和一个 feign.Contract
。可以使用 @FeignClient
标注的 contextId
属性覆盖该组件集的名称。
Spring Cloud 允许您通过使用 @FeignClient
声明附加配置(在 FeignClientsConfiguration
中)来完全控制 feign 客户端。示例:
@FeignClient(name = "stores", configuration = FooConfiguration.class)
public interface StoreClient {
//..
}
在这种情况下,客户端由 FeignClientsConfiguration
中的组件以及 FooConfiguration
中的任何组件构成(后者将覆盖前者)。
|
除更改 |
以前,使用 url
属性不需要 name
属性。现在需要使用 name
。
name
和 url
属性支持占位符。
@FeignClient(name = "${feign.name}", url = "${feign.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
。如果在类路径中没有一个,则使用默认的 feign 客户端。
|
若要使用 OkHttpClient 支持的 Feign 客户端和 Http2Client Feign 客户端,请确保您要使用的客户端在类路径中,并将 spring.cloud.openfeign.okhttp.enabled
或 spring.cloud.openfeign.http2client.enabled
分别设为 true
。
对于 Apache HttpClient 5 支持的 Feign 客户端,只需确保 HttpClient 5 在类路径中即可,但您仍可以通过将 spring.cloud.openfeign.httpclient.hc5.enabled
设为 false
来禁用它在 Feign 客户端中的使用。使用 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,带有 httpclient.http2
前缀的那些属性适用于 Http2Client。您可以在附录中找到可以自定义的完整属性列表。如果您无法使用属性配置 Apache HttpClient 5,则有一个 HttpClientBuilderCustomizer
接口用于以编程方式进行配置。
从 Spring Cloud OpenFeign 4 开始,不再支持 Feign Apache HttpClient 4。我们建议改用 Apache HttpClient 5。 |
Spring Cloud OpenFeign 不 为 feign 提供以下默认 Bean,但仍从应用程序上下文中查找这些类型的 Bean 以创建 feign 客户端:
-
Logger.Level
-
Retryer
-
ErrorDecoder
-
Request.Options
-
Collection<RequestInterceptor>
-
SetterFactory
-
QueryMapEncoder
-
Capability
(默认提供MicrometerObservationCapability
和CachingCapability
)
默认情况下,创建一个 Retryer.NEVER_RETRY
Bean,其类型为 Retryer
,这将禁用重试。请注意,此重试行为与 Feign 默认行为不同,在 Feign 默认行为中,它将自动重试 IOException,将它们视为与网络相关的瞬态异常,以及 ErrorDecoder 引发的任何 RetryableException。
创建一种类型的一个 Bean,并将其放置在 @FeignClient
配置(例如上面的 FooConfiguration
)中,让您可以覆盖所述的每个 Bean。示例:
@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
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
,它还与 @FeignClient
name
和 @FeignClient
contextId
构成别名。在负载均衡场景中,它还对应服务器应用程序的 serviceId
,此 serviceId
用于检索实例。指定的解码器、重试器和其他类的指定类必须在 Spring 上下文中有一个 bean 或者有一个默认构造函数。
可以在 @EnableFeignClients
属性 defaultConfiguration
中指定默认配置,类似于上述所述。不同之处在于,此配置将适用于 所有 Feign 客户端。
如果你更愿意使用配置属性配置所有 @FeignClient
,则可以使用 default
feign 名称创建配置属性。
你可以使用 spring.cloud.openfeign.client.config.feignName.defaultQueryParameters
和 spring.cloud.openfeign.client.config.feignName.defaultRequestHeaders
来指定将随名为 feignName
的客户端的每个请求发送的查询参数和标头。
application.yml
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 的多个 feign 客户端,以便它们指向同一服务器,但每个客户端具有不同的自定义配置,那么我们必须使用 @FeignClient
的 contextId
属性,以避免这些配置 bean 发生名称冲突。
@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class)
public interface FooClient {
//..
}
@FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class)
public interface BarClient {
//..
}
还可以配置 FeignClient 以不从父上下文中继承 bean。你可以通过在 FeignClientConfigurer
bean 中覆盖 inheritParentConfiguration()
并返回 false
来做到这一点:
@Configuration
public class CustomConfiguration {
@Bean
public FeignClientConfigurer feignClientConfigurer() {
return new FeignClientConfigurer() {
@Override
public boolean inheritParentConfiguration() {
return false;
}
};
}
}
默认情况下,Feign 客户端不编码斜杠 |
Timeout Handling
我们可以配置默认客户端和命名客户端上的超时。OpenFeign 使用两个超时参数:
-
connectTimeout
阻止由于服务器处理时间长而阻塞调用者。 -
readTimeout
从建立连接时开始应用,并在返回响应需要太长时间时触发。
如果服务器未运行或不可用,则数据包会导致 connection refused。通信以错误消息结束或以失败告终。如果将 |
Creating Feign Clients Manually
在某些情况下,可能有必要以不使用上述方法的方式自定义 Feign 客户端。在这种情况下,您可以使用 Feign Builder API 创建客户端。以下是一个示例,它使用相同的界面创建了两个 Feign 客户端,但使用单独的请求拦截器配置了每个客户端。
@Import(FeignClientsConfiguration.class)
class FooController {
private FooClient fooClient;
private FooClient adminClient;
@Autowired
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");
}
}
在上述示例中 |
|
Feign |
你还可以使用 Builder
来配置 FeignClient 以不从父上下文中继承 bean。你可以通过在 Builder
上调用 inheritParentContext(false)
来做到这一点。
Feign Spring Cloud CircuitBreaker Support
如果 Spring Cloud CircuitBreaker 位于类路径中并且 spring.cloud.openfeign.circuitbreaker.enabled=true
,则 Feign 将使用断路器包装所有方法。
要按客户端禁用 Spring Cloud CircuitBreaker 支持,请创建一个带有“prototype”范围的纯 Feign.Builder
,例如:
@Configuration
public class FooConfiguration {
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder() {
return Feign.builder();
}
}
断路器名称遵循以下模式:<feignClientClassName>#<calledMethod>(<parameterTypes>)
。使用具有 FooClient
接口的 @FeignClient
进行调用,且被调用的接口方法没有参数,则断路器名称将为 FooClient#bar()
。
截至 2020.0.2,断路器名称模式已从 |
通过提供 CircuitBreakerNameResolver
的 bean,你可以更改断路器名称模式。
@Configuration
public class FooConfiguration {
@Bean
public CircuitBreakerNameResolver circuitBreakerNameResolver() {
return (String feignClientName, Target<?> target, Method method) -> feignClientName + "_" + method.getName();
}
}
要启用 Spring Cloud CircuitBreaker 组,请将 spring.cloud.openfeign.circuitbreaker.group.enabled
属性设置为 true
(默认为 false
)。
Configuring CircuitBreakers With Configuration Properties
你可以通过配置属性配置断路器。
例如,如果你有这个 Feign 客户端
@FeignClient(url = "http://localhost:8080")
public interface DemoClient {
@GetMapping("demo")
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 之前使用的断路器名称,你可以将 |
Feign Spring Cloud CircuitBreaker Fallbacks
Spring Cloud CircuitBreaker 支持回退概念:在服务调用失败或服务熔断时执行的默认代码路径。要针对给定的 @FeignClient
启用回退,请将 fallback
属性设置为实现回退的类名。还需要将你的实现声明为 Spring Bean。
@FeignClient(name = "test", url = "http://localhost:${server.port}/", fallback = Fallback.class)
protected interface TestClient {
@GetMapping("/hello")
Hello getHello();
@GetMapping("/hellonotfound")
String getException();
}
@Component
static class Fallback implements TestClient {
@Override
public Hello getHello() {
throw new NoFallbackAvailableException("Boom!", new RuntimeException());
}
@Override
public String getException() {
return "Fixed response";
}
}
如果需要访问触发回退的原因,可以在 @FeignClient
内使用 fallbackFactory
属性。
@FeignClient(name = "testClientWithFactory", url = "http://localhost:${server.port}/",
fallbackFactory = TestFallbackFactory.class)
protected interface TestClientWithFactory {
@GetMapping("/hello")
Hello getHello();
@GetMapping("/hellonotfound")
String getException();
}
@Component
static class TestFallbackFactory implements FallbackFactory<FallbackWithFactory> {
@Override
public FallbackWithFactory create(Throwable cause) {
return new FallbackWithFactory();
}
}
static class FallbackWithFactory implements TestClientWithFactory {
@Override
public Hello getHello() {
throw new NoFallbackAvailableException("Boom!", new RuntimeException());
}
@Override
public String getException() {
return "Fixed response";
}
}
Feign and @Primary
在将 Feign 与 Spring Cloud CircuitBreaker 回退一起使用时,ApplicationContext
中有多个相同类型的 Bean。由于没有确切的一个 Bean 或被标记为主 Bean 的 Bean,因此会导致 @Autowired
无法使用。为了解决此问题,Spring Cloud OpenFeign 将所有 Feign 实例标记为 @Primary
,以便 Spring Framework 知道注入哪个 Bean。在某些情况下,可能不希望这样做。要关闭此行为,请将 @FeignClient
的 primary
属性设置为 false。
@FeignClient(name = "hello", primary = false)
public interface HelloClient {
// methods here
}
Feign Inheritance Support
Feign 通过单继承接口支持样板 API。这使你可以将常见操作分组到方便的基本接口中。
public interface UserService {
@GetMapping("/users/{id}")
User getUser(@PathVariable("id") long id);
}
@RestController
public class UserResource implements UserService {
}
package project.user;
@FeignClient("users")
public interface UserClient extends UserService {
}
@FeignClient
接口不应在服务器和客户端之间共享,而且使用 @RequestMapping
在类级别注释 @FeignClient
接口也不再受支持。
[[feign-request/response-compression]]=== 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 使用“透明”压缩,当 |
Feign logging
为创建的每个 Feign 客户端都会创建一个日志记录器。默认情况下,日志记录器的名称是用于创建 Feign 客户端的接口的全类名。Feign 日志记录只响应 DEBUG
级别。
logging.level.project.user.UserClient: DEBUG
你可以针对每个客户端配置的 Logger.Level
对象会告知 Feign 记录的详细信息。选项包括:
-
NONE
, No logging (DEFAULT). -
BASIC
,仅记录请求方法和 URL 以及响应状态代码和执行时间。 -
HEADERS
,记录请求和响应标头以及基本信息。 -
FULL
,记录请求和响应的标头、正文和元数据。
例如,下面的示例会将 Logger.Level
设置为 FULL
:
@Configuration
public class FooConfiguration {
@Bean
Logger.Level feignLoggerLevel() {
return Logger.Level.FULL;
}
}
Feign Capability support
Feign 功能公开了核心 Feign 组件,以便可以修改这些组件。例如,功能可以获取 Client
、_decorate_它,并将装饰后的实例返回给 Feign。Micrometer 的支持就是此功能的出色实际示例。请参阅 Micrometer Support。
创建一或多个 Capability
Bean 并将其置于 @FeignClient
配置中,这样可以注册这些 Bean 并修改所涉及客户端的行为。
@Configuration
public class FooConfiguration {
@Bean
Capability customCapability() {
return new CustomCapability();
}
}
Micrometer Support
如果满足以下所有条件,则会创建一个 MicrometerObservationCapability
Bean 并进行注册,以便你的 Feign 客户端可以由 Micrometer 观测:
-
feign-micrometer
在类路径上 -
一个
ObservationRegistry
bean 可用 -
feign 微米属性设置为
true
(默认情况下)-
spring.cloud.openfeign.micrometer.enabled=true
(for all clients) -
spring.cloud.openfeign.client.config.feignName.micrometer.enabled=true
(对于单个客户端)
-
如果你的应用程序已经使用了 Micrometer,启用此功能只需将 |
你还可以通过以下方式禁用该功能:
-
从类路径中排除
feign-micrometer
-
将 feign 微米属性之一设置为
false
-
spring.cloud.openfeign.micrometer.enabled=false
-
spring.cloud.openfeign.client.config.feignName.micrometer.enabled=false
-
|
你还可以通过注册自己的 Bean 来自定义 MicrometerObservationCapability
:
@Configuration
public class FooConfiguration {
@Bean
public MicrometerObservationCapability micrometerObservationCapability(ObservationRegistry registry) {
return new MicrometerObservationCapability(registry);
}
}
仍然可以使用 MicrometerCapability
与 Feign(仅指标支持),你需要禁用 Micrometer 支持(spring.cloud.openfeign.micrometer.enabled=false
)并创建一个 MicrometerCapability
Bean:
@Configuration
public class FooConfiguration {
@Bean
public MicrometerCapability micrometerCapability(MeterRegistry meterRegistry) {
return new MicrometerCapability(meterRegistry);
}
}
Feign Caching
如果使用了 @EnableCaching
注解,则会创建并注册 CachingCapability
Bean,以便你的 Feign 客户端可以识别其界面上的 @Cache
注解:
public interface DemoClient {
@GetMapping("/demo/{filterParam}")
@Cacheable(cacheNames = "demo-cache", key = "#keyParam")
String demoEndpoint(String keyParam, @PathVariable String filterParam);
}
你还可以通过属性 spring.cloud.openfeign.cache.enabled=false
禁用该功能。
Feign @QueryMap support
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
类:
@FeignClient("demo")
public interface DemoTemplate {
@GetMapping(path = "/demo")
String demoEndpoint(@SpringQueryMap Params params);
}
如果您需要更多控制生成的查询参数映射,则可以实现自定义 QueryMapEncoder
Bean。
HATEOAS support
Spring 提供了一些 API 来创建遵循 HATEOAS原则的 REST 表示: Spring Hateoas和 Spring Data REST。
如果您的项目使用 org.springframework.boot:spring-boot-starter-hateoas
starter 或 org.springframework.boot:spring-boot-starter-data-rest
starter,则默认启用 Feign HATEOAS 支持。
启用 HATEOAS 支持后,允许 Feign 客户端序列化和反序列化 HATEOAS 表示模型: EntityModel、 CollectionModel和 PagedModel。
@FeignClient("demo")
public interface DemoTemplate {
@GetMapping(path = "/stores")
CollectionModel<Store> getStores();
}
Spring @MatrixVariable Support
Spring Cloud OpenFeign 为 Spring @MatrixVariable
注释提供支持。
如果将映射作为方法参数传递,则通过使用 =
连接映射中的键值对来创建 @MatrixVariable
路径段。
如果传递不同的对象,则使用 =
将 @MatrixVariable
注释中提供的 name
(如果已定义)或带注释的变量名称与提供的函数参数连接。
- IMPORTANT
-
Even though, on the server side, Spring does not require the users to name the path segment placeholder same as the matrix variable name, since it would be too ambiguous on the client side, Spring Cloud OpenFeign requires that you add a path segment placeholder with a name matching either the
name
provided in the@MatrixVariable
annotation (if defined) or the annotated variable name.
例如:
@GetMapping("/objects/links/{matrixVars}")
Map<String, List<String>> getObjects(@MatrixVariable Map<String, List<String>> matrixVars);
请注意,变量名称和路径段占位符都称为 matrixVars
。
@FeignClient("demo")
public interface DemoTemplate {
@GetMapping(path = "/stores")
CollectionModel<Store> getStores();
}
Feign CollectionFormat
support
通过提供 @CollectionFormat
注释,我们支持 feign.CollectionFormat
。您可以通过将所需的 feign.CollectionFormat
作为注释值传递,用它注释 Feign 客户端方法(或整个类以影响所有方法)。
在以下示例中,使用 CSV
格式来处理方法,而不是默认的 EXPLODED
格式。
@FeignClient(name = "demo")
protected interface DemoFeignClient {
@CollectionFormat(feign.CollectionFormat.CSV)
@GetMapping(path = "/test")
ResponseEntity performRequest(String test);
}
Reactive Support
因为 OpenFeign project目前不支持响应式客户端,例如 Spring WebClient,所以 Spring Cloud OpenFeign 也不支持。
由于 Spring Cloud OpenFeign 项目现在被认为已完成功能,因此即使它在上游项目中可用,我们也不计划添加支持。我们建议改为迁移到 Spring Interface Clients。它同时支持阻塞和响应式堆栈。
在完成之前,我们建议针对 Spring WebClient 支持使用 feign-reactive。
Spring Data Support
如果类路径中存在 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
Support
如果启用了 Feign 客户端刷新,则会使用以下内容创建每个 Feign 客户端:
-
将
feign.Request.Options
作为 refresh 作用域 bean。这意味着connectTimeout
和readTimeout
等属性可以针对任何 Feign 客户端实例进行刷新。 -
包装在
org.springframework.cloud.openfeign.RefreshableUrl
下 URL。这意味着如果使用spring.cloud.openfeign.client.config.{feignName}.url
属性定义,则 Feign 客户端的 URL 可以针对任何 Feign 客户端实例进行刷新。
您可以通过 POST /actuator/refresh
刷新这些属性。
默认禁用 Feign 客户端中的刷新行为。使用以下属性启用刷新行为:
spring.cloud.openfeign.client.refresh-enabled=true
不要使用 |
OAuth2 Support
通过将 spring-boot-starter-oauth2-client
依赖项添加到项目并设置以下标记,可以启用 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
-
Using the
serviceId
as OAuth2 client registrationId is convenient for load-balanced Feign clients. For non-load-balanced ones, the property-basedclientRegistrationId
is a suitable approach. - TIP
-
If you do not want to use the default setup for the
OAuth2AuthorizedClientManager
, you can just instantiate a bean of this type in your configuration.
Transform the load-balanced HTTP request
您可以使用选定的 ServiceInstance
来转换负载均衡的 HTTP 请求。
对于 Request
,您需要按如下所示实现和定义 LoadBalancerFeignRequestTransformer
:
@Bean
public LoadBalancerFeignRequestTransformer transformer() {
return new LoadBalancerFeignRequestTransformer() {
@Override
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 Support
可以通过设置以下标记来启用 X-Forwarded-Host
和 X-Forwarded-Proto
的支持:
spring.cloud.loadbalancer.x-forwarded.enabled=true
Supported Ways To Provide URL To A Feign Client
您可以使用以下任何一种方式为 Feign 客户端提供 URL:
Case | Example | Details |
---|---|---|
URL 在 |
|
URL 从注释的 |
URL 在 |
|
URL 从注释的 |
URL 未在 |
|
URL 是从配置属性中解析的,没有负载均衡。如果`spring.cloud.openfeign.client.refresh-enabled=true`,那么配置属性中定义的 URL 可以按 Spring RefreshScope Support 中的描述进行刷新。 |
URL 在 |
|
URL 是从 |
AOT and Native Image Support
Spring Cloud OpenFeign 支持 Spring AOT 转换和本地映像,但仅当禁用刷新模式、停用 Feign 客户端刷新(默认设置)和 xref:spring-cloud-openfeign.adoc#attribute-resolution-mode[lazy @FeignClient
属性分辨率(默认设置)时才支持。
如果你想在 AOT 或原生镜像模式下运行 Spring Cloud OpenFeign 客户端,请确保将 spring.cloud.refresh.enabled
设置为 false
。
如果你想在 AOT 或原生镜像模式下运行 Spring Cloud OpenFeign 客户端,请确保未将 |
如果你想在 AOT 或原生镜像模式下运行 Spring Cloud OpenFeign 客户端,请确保未将 |
不过,如果你通过属性设置 |
Configuration properties
要查看所有 Spring Cloud OpenFeign 相关配置属性的列表,请查看 the Appendix page。