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 客户端。

Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Eureka, Spring Cloud CircuitBreaker, as well as Spring Cloud LoadBalancer to provide a load-balanced http client when using Feign.

How to Include Feign

要将 Feign 包含在你的项目中,请使用组 `org.springframework.cloud`和构件 ID `spring-cloud-starter-openfeign`的启动器。有关使用当前 Spring Cloud 发布版本来设置你的构建系统的详细信息,请参阅 Spring Cloud Project page

To include Feign in your project use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-openfeign. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

Spring Boot 应用示例

Example spring boot app

@SpringBootApplication
@EnableFeignClients
public class Application {

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

}
StoreClient.java
@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`值。

In the @FeignClient annotation the String value ("stores" above) is an arbitrary client name, which is used to create a Spring Cloud LoadBalancer client. You can also specify a URL using the url attribute (absolute value or just a hostname). The name of the bean in the application context is the fully qualified name of the interface. To specify your own alias value you can use the qualifiers value of the @FeignClient annotation.

上述负载均衡器客户端需要发现“stores”服务的物理地址。如果你的应用程序是 Eureka 客户端,那么它将在 Eureka 服务注册表中解析服务。如果你不想使用 Eureka,则可以使用 SimpleDiscoveryClient在外部配置中配置服务器列表。

The load-balancer client above will want to discover the physical addresses for the "stores" service. If your application is a Eureka client then it will resolve the service in the Eureka service registry. If you don’t want to use Eureka, you can configure a list of servers in your external configuration using SimpleDiscoveryClient.

Spring Cloud OpenFeign 支持 Spring Cloud LoadBalancer 的阻塞模式中可用的所有功能。你可以在 project documentation中阅读更多相关信息。

Spring Cloud OpenFeign supports all the features available for the blocking mode of Spring Cloud LoadBalancer. You can read more about them in the project documentation.

要使用 @EnableFeignClients 在带 @Configuration 注释的类上进行注释,请确保指定客户端所在的位置,例如 @EnableFeignClients(basePackages = "com.example.clients"),或显式列出它们 @EnableFeignClients(clients = InventoryServiceFeignClient.class)

To use @EnableFeignClients annotation on @Configuration-annotated-classes, make sure to specify where the clients are located, for example: @EnableFeignClients(basePackages = "com.example.clients") or list them explicitly: @EnableFeignClients(clients = InventoryServiceFeignClient.class)

Attribute resolution mode

在创建 Feign 客户端 Bean 时,我们会解析通过 @FeignClient 标注传递的值。从 4.x 开始,这些值会急切解析。这对于大多数用例来说都是一个好方法,并且允许 AOT 支持。

While creating Feign client beans, we resolve the values passed via the @FeignClient annotation. As of 4.x, the values are being resolved eagerly. This is a good solution for most use-cases, and it also allows for AOT support.

如果您需要属性延迟解析,请将 spring.cloud.openfeign.lazy-attributes-resolution 属性值设为 true

If you need the attributes to be resolved lazily, set the spring.cloud.openfeign.lazy-attributes-resolution property value to true.

对于 Spring Cloud Contract 测试集成,应使用延迟属性解析。

For Spring Cloud Contract test integration, lazy attribute resolution should be used.

Overriding Feign Defaults

Spring Cloud 对 Feign 支持中的一个核心概念是已命名客户端。每个 feign 客户端是一个组件集的一部分,这些组件共同在按需联系远程服务器时协同工作,并且该组件集有一个名称,您会使用 @FeignClient 标注将其作为应用程序开发人员提供。Spring Cloud 使用 FeignClientsConfiguration 为每个已命名客户端按需创建一个 ApplicationContext 作为 Ensemble。这(除其他内容外)包含一个 feign.Decoder、一个 feign.Encoder 和一个 feign.Contract。可以使用 @FeignClient 标注的 contextId 属性覆盖该组件集的名称。

A central concept in Spring Cloud’s Feign support is that of the named client. Each feign client is part of an ensemble of components that work together to contact a remote server on demand, and the ensemble has a name that you give it as an application developer using the @FeignClient annotation. Spring Cloud creates a new ensemble as an ApplicationContext on demand for each named client using FeignClientsConfiguration. This contains (amongst other things) an feign.Decoder, a feign.Encoder, and a feign.Contract. It is possible to override the name of that ensemble by using the contextId attribute of the @FeignClient annotation.

Spring Cloud 允许您通过使用 @FeignClient 声明附加配置(在 FeignClientsConfiguration 中)来完全控制 feign 客户端。示例:

Spring Cloud lets you take full control of the feign client by declaring additional configuration (on top of the FeignClientsConfiguration) using @FeignClient. Example:

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

在这种情况下,客户端由 FeignClientsConfiguration 中的组件以及 FooConfiguration 中的任何组件构成(后者将覆盖前者)。

In this case the client is composed from the components already in FeignClientsConfiguration together with any in FooConfiguration (where the latter will override the former).

FooConfiguration 无需使用 @Configuration 进行注释。但是,如果进行了注释,请注意将其从任何其他 @ComponentScan 中排除,否则将包括此配置,因为当指定时,它将成为 feign.Decoderfeign.Encoderfeign.Contract 等的默认源。可以通过将其放入与任何 @ComponentScan@SpringBootApplication 不重叠的单独包中来避免这种情况,或者可以在 @ComponentScan 中明确排除它。

FooConfiguration does not need to be annotated with @Configuration. However, if it is, then take care to exclude it from any @ComponentScan that would otherwise include this configuration as it will become the default source for feign.Decoder, feign.Encoder, feign.Contract, etc., when specified. This can be avoided by putting it in a separate, non-overlapping package from any @ComponentScan or @SpringBootApplication, or it can be explicitly excluded in @ComponentScan.

除更改 ApplicationContext 集成名称外,使用 @FeignClient 注释的 contextId 属性还将覆盖客户端名称的别名,并将其用作为此客户端创建的配置 Bean 名称的一部分。

Using contextId attribute of the @FeignClient annotation in addition to changing the name of the ApplicationContext ensemble, it will override the alias of the client name and it will be used as part of the name of the configuration bean created for that client.

以前,使用 url 属性不需要 name 属性。现在需要使用 name

Previously, using the url attribute, did not require the name attribute. Using name is now required.

nameurl 属性支持占位符。

Placeholders are supported in the name and url attributes.

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

Spring Cloud OpenFeign 为 feign 提供以下默认 Bean(BeanType BeanName:ClassName):

Spring Cloud OpenFeign provides the following beans by default for feign (BeanType beanName: ClassName):

  • Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder)

  • Encoder feignEncoder: SpringEncoder

  • Logger feignLogger: Slf4jLogger

  • MicrometerObservationCapability micrometerObservationCapability: If feign-micrometer is on the classpath and ObservationRegistry is available

  • MicrometerCapability micrometerCapability: If feign-micrometer is on the classpath, MeterRegistry is available and ObservationRegistry is not available

  • CachingCapability cachingCapability: If @EnableCaching annotation is used. Can be disabled via spring.cloud.openfeign.cache.enabled.

  • Contract feignContract: SpringMvcContract

  • Feign.Builder feignBuilder: FeignCircuitBreaker.Builder

  • Client feignClient: If Spring Cloud LoadBalancer is on the classpath, FeignBlockingLoadBalancerClient is used. If none of them is on the classpath, the default feign client is used.

spring-cloud-starter-openfeign 支持 spring-cloud-starter-loadbalancer。但是,由于这是一项可选依赖项,如果您想使用它,需要确保将其添加到您的项目中。

spring-cloud-starter-openfeign supports spring-cloud-starter-loadbalancer. However, as is an optional dependency, you need to make sure it has been added to your project if you want to use it.

若要使用 OkHttpClient 支持的 Feign 客户端和 Http2Client Feign 客户端,请确保您要使用的客户端在类路径中,并将 spring.cloud.openfeign.okhttp.enabledspring.cloud.openfeign.http2client.enabled 分别设为 true

To use OkHttpClient-backed Feign clients and Http2Client Feign clients, make sure that the client you want to use is on the classpath and set spring.cloud.openfeign.okhttp.enabled or spring.cloud.openfeign.http2client.enabled to true respectively.

对于 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 客户端。

When it comes to the Apache HttpClient 5-backed Feign clients, it’s enough to ensure HttpClient 5 is on the classpath, but you can still disable its use for Feign Clients by setting spring.cloud.openfeign.httpclient.hc5.enabled to false. You can customize the HTTP client used by providing a bean of either org.apache.hc.client5.http.impl.classic.CloseableHttpClient when using Apache HC5.

您可以通过设置 spring.cloud.openfeign.httpclient.xxx 属性中的值来进一步自定义 http 客户端。仅带有 httpclient 前缀的那些属性将适用于所有客户端,带有 httpclient.hc5 前缀的那些属性适用于 Apache HttpClient 5,带有 httpclient.okhttp 前缀的那些属性适用于 OkHttpClient,带有 httpclient.http2 前缀的那些属性适用于 Http2Client。您可以在附录中找到可以自定义的完整属性列表。如果您无法使用属性配置 Apache HttpClient 5,则有一个 HttpClientBuilderCustomizer 接口用于以编程方式进行配置。

You can further customise http clients by setting values in the spring.cloud.openfeign.httpclient.xxx properties. The ones prefixed just with httpclient will work for all the clients, the ones prefixed with httpclient.hc5 to Apache HttpClient 5, the ones prefixed with httpclient.okhttp to OkHttpClient and the ones prefixed with httpclient.http2 to Http2Client. You can find a full list of properties you can customise in the appendix. If you can not configure Apache HttpClient 5 by using properties, there is an HttpClientBuilderCustomizer interface for programmatic configuration.

从 Spring Cloud OpenFeign 4 开始,不再支持 Feign Apache HttpClient 4。我们建议改用 Apache HttpClient 5。

Starting with Spring Cloud OpenFeign 4, the Feign Apache HttpClient 4 is no longer supported. We suggest using Apache HttpClient 5 instead.

Spring Cloud OpenFeign 为 feign 提供以下默认 Bean,但仍从应用程序上下文中查找这些类型的 Bean 以创建 feign 客户端:

Spring Cloud OpenFeign does not provide the following beans by default for feign, but still looks up beans of these types from the application context to create the feign client:

  • Logger.Level

  • Retryer

  • ErrorDecoder

  • Request.Options

  • Collection<RequestInterceptor>

  • SetterFactory

  • QueryMapEncoder

  • Capability (MicrometerObservationCapability and CachingCapability are provided by default)

默认情况下,创建一个 Retryer.NEVER_RETRY Bean,其类型为 Retryer,这将禁用重试。请注意,此重试行为与 Feign 默认行为不同,在 Feign 默认行为中,它将自动重试 IOException,将它们视为与网络相关的瞬态异常,以及 ErrorDecoder 引发的任何 RetryableException。

A bean of Retryer.NEVER_RETRY with the type Retryer is created by default, which will disable retrying. Notice this retrying behavior is different from the Feign default one, where it will automatically retry IOExceptions, treating them as transient network related exceptions, and any RetryableException thrown from an ErrorDecoder.

创建一种类型的一个 Bean,并将其放置在 @FeignClient 配置(例如上面的 FooConfiguration)中,让您可以覆盖所述的每个 Bean。示例:

Creating a bean of one of those type and placing it in a @FeignClient configuration (such as FooConfiguration above) allows you to override each one of the beans described. Example:

@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 集合中。

This replaces the SpringMvcContract with feign.Contract.Default and adds a RequestInterceptor to the collection of RequestInterceptor.

我们还可以使用配置属性配置 @FeignClient

@FeignClient also can be configured using configuration properties.

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 或者有一个默认构造函数。

feignName in this example refers to @FeignClient value, that is also aliased with @FeignClient name and @FeignClient contextId. In a load-balanced scenario, it also corresponds to the serviceId of the server app that will be used to retrieve the instances. The specified classes for decoders, retryer and other ones must have a bean in the Spring context or have a default constructor.

可以在 @EnableFeignClients 属性 defaultConfiguration 中指定默认配置,类似于上述所述。不同之处在于,此配置将适用于 所有 Feign 客户端。

Default configurations can be specified in the @EnableFeignClients attribute defaultConfiguration in a similar manner as described above. The difference is that this configuration will apply to all feign clients.

如果你更愿意使用配置属性配置所有 @FeignClient,则可以使用 default feign 名称创建配置属性。

If you prefer using configuration properties to configure all @FeignClient, you can create configuration properties with default feign name.

你可以使用 spring.cloud.openfeign.client.config.feignName.defaultQueryParametersspring.cloud.openfeign.client.config.feignName.defaultRequestHeaders 来指定将随名为 feignName 的客户端的每个请求发送的查询参数和标头。

You can use spring.cloud.openfeign.client.config.feignName.defaultQueryParameters and spring.cloud.openfeign.client.config.feignName.defaultRequestHeaders to specify query parameters and headers that will be sent with every request of the client named 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

If we create both @Configuration bean and configuration properties, configuration properties will win. It will override @Configuration values. But if you want to change the priority to @Configuration, you can change spring.cloud.openfeign.client.default-to-properties to false.

如果我们要创建具有相同名称或 url 的多个 feign 客户端,以便它们指向同一服务器,但每个客户端具有不同的自定义配置,那么我们必须使用 @FeignClientcontextId 属性,以避免这些配置 bean 发生名称冲突。

If we want to create multiple feign clients with the same name or url so that they would point to the same server but each with a different custom configuration then we have to use contextId attribute of the @FeignClient in order to avoid name collision of these configuration beans.

@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 来做到这一点:

It is also possible to configure FeignClient not to inherit beans from the parent context. You can do this by overriding the inheritParentConfiguration() in a FeignClientConfigurer bean to return false:

@Configuration
public class CustomConfiguration {
	@Bean
	public FeignClientConfigurer feignClientConfigurer() {
		return new FeignClientConfigurer() {
			@Override
			public boolean inheritParentConfiguration() {
				 return false;
			}
		};
	}
}

默认情况下,Feign 客户端不编码斜杠 / 字符。您可以通过将 spring.cloud.openfeign.client.decodeSlash 的值设置 false 来更改此行为。

By default, Feign clients do not encode slash / characters. You can change this behaviour, by setting the value of spring.cloud.openfeign.client.decodeSlash to false.

SpringEncoder configuration

在我们提供的 SpringEncoder 中,我们将二进制内容类型的字符集设置为 null,并将所有其他内容类型的字符集设置为 UTF-8

In the SpringEncoder that we provide, we set null charset for binary content types and UTF-8 for all the other ones.

你可以通过将 spring.cloud.openfeign.encoder.charset-from-content-type 的值设置为 true 来修改此行为,以便从 Content-Type 标头字符集中派生字符集。

You can modify this behaviour to derive the charset from the Content-Type header charset instead by setting the value of spring.cloud.openfeign.encoder.charset-from-content-type to true.

Timeout Handling

我们可以配置默认客户端和命名客户端上的超时。OpenFeign 使用两个超时参数:

We can configure timeouts on both the default and the named client. OpenFeign works with two timeout parameters:

  • connectTimeout prevents blocking the caller due to the long server processing time.

  • readTimeout is applied from the time of connection establishment and is triggered when returning the response takes too long.

如果服务器未运行或不可用,则数据包会导致 connection refused。通信以错误消息结束或以失败告终。如果将 connectTimeout 设置得很低,则 before 时可能会发生这种情况。执行查找和接收此类数据包所花费的时间占此延迟的很大一部分。它会根据需要进行 DNS 查找的远程主机而发生变化。

In case the server is not running or available a packet results in connection refused. The communication ends either with an error message or in a fallback. This can happen before the connectTimeout if it is set very low. The time taken to perform a lookup and to receive such a packet causes a significant part of this delay. It is subject to change based on the remote host that involves a DNS lookup.

Creating Feign Clients Manually

在某些情况下,可能有必要以不使用上述方法的方式自定义 Feign 客户端。在这种情况下,您可以使用 Feign Builder API 创建客户端。以下是一个示例,它使用相同的界面创建了两个 Feign 客户端,但使用单独的请求拦截器配置了每个客户端。

In some cases it might be necessary to customize your Feign Clients in a way that is not possible using the methods above. In this case you can create Clients using the Feign Builder API. Below is an example which creates two Feign Clients with the same interface but configures each one with a separate request interceptor.

@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");
	}
}

在上述示例中 FeignClientsConfiguration.class 是 Spring Cloud OpenFeign 提供的默认配置。

In the above example FeignClientsConfiguration.class is the default configuration provided by Spring Cloud OpenFeign.

PROD-SVC 是客户端将向其发送请求的服务的名称。

PROD-SVC is the name of the service the Clients will be making requests to.

Feign Contract 对象定义了在接口上有效的注释和值。@{4} bean 提供对 SpringMVC 注释的支持,而不是默认的 Feign 本机注释。

The Feign Contract object defines what annotations and values are valid on interfaces. The autowired Contract bean provides supports for SpringMVC annotations, instead of the default Feign native annotations.

你还可以使用 Builder 来配置 FeignClient 以不从父上下文中继承 bean。你可以通过在 Builder 上调用 inheritParentContext(false) 来做到这一点。

You can also use the Builder`to configure FeignClient not to inherit beans from the parent context. You can do this by overriding calling `inheritParentContext(false) on the Builder.

Feign Spring Cloud CircuitBreaker Support

如果 Spring Cloud CircuitBreaker 位于类路径中并且 spring.cloud.openfeign.circuitbreaker.enabled=true,则 Feign 将使用断路器包装所有方法。

If Spring Cloud CircuitBreaker is on the classpath and spring.cloud.openfeign.circuitbreaker.enabled=true, Feign will wrap all methods with a circuit breaker.

要按客户端禁用 Spring Cloud CircuitBreaker 支持,请创建一个带有“prototype”范围的纯 Feign.Builder,例如:

To disable Spring Cloud CircuitBreaker support on a per-client basis create a vanilla Feign.Builder with the "prototype" scope, e.g.:

@Configuration
public class FooConfiguration {
	@Bean
	@Scope("prototype")
	public Feign.Builder feignBuilder() {
		return Feign.builder();
	}
}

断路器名称遵循以下模式:<feignClientClassName>#<calledMethod>(<parameterTypes>)。使用具有 FooClient 接口的 @FeignClient 进行调用,且被调用的接口方法没有参数,则断路器名称将为 FooClient#bar()

The circuit breaker name follows this pattern <feignClientClassName>#<calledMethod>(<parameterTypes>). When calling a @FeignClient with FooClient interface and the called interface method that has no parameters is bar then the circuit breaker name will be FooClient#bar().

截至 2020.0.2,断路器名称模式已从 <feignClientName>_<calledMethod> 更改。使用 2020.0.4 引入的 CircuitBreakerNameResolver,断路器名称可以保留旧模式。

As of 2020.0.2, the circuit breaker name pattern has changed from <feignClientName>_<calledMethod>. Using CircuitBreakerNameResolver introduced in 2020.0.4, circuit breaker names can retain the old pattern.

通过提供 CircuitBreakerNameResolver 的 bean,你可以更改断路器名称模式。

Providing a bean of CircuitBreakerNameResolver, you can change the circuit breaker name pattern.

@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)。

To enable Spring Cloud CircuitBreaker group set the spring.cloud.openfeign.circuitbreaker.group.enabled property to true (by default false).

Configuring CircuitBreakers With Configuration Properties

你可以通过配置属性配置断路器。

You can configure CircuitBreakers via configuration properties.

例如,如果你有这个 Feign 客户端

For example, if you had this Feign client

@FeignClient(url = "http://localhost:8080")
public interface DemoClient {

    @GetMapping("demo")
    String getDemo();
}

使用配置属性进行配置的方法如下:

You could configure it using configuration properties by doing the following

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

If you want to switch back to the circuit breaker names used prior to Spring Cloud 2022.0.0 you can set spring.cloud.openfeign.circuitbreaker.alphanumeric-ids.enabled to false.

Feign Spring Cloud CircuitBreaker Fallbacks

Spring Cloud CircuitBreaker 支持回退概念:在服务调用失败或服务熔断时执行的默认代码路径。要针对给定的 @FeignClient 启用回退,请将 fallback 属性设置为实现回退的类名。还需要将你的实现声明为 Spring Bean。

Spring Cloud CircuitBreaker supports the notion of a fallback: a default code path that is executed when the circuit is open or there is an error. To enable fallbacks for a given @FeignClient set the fallback attribute to the class name that implements the fallback. You also need to declare your implementation as a 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 属性。

If one needs access to the cause that made the fallback trigger, one can use the fallbackFactory attribute inside @FeignClient.

@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。在某些情况下,可能不希望这样做。要关闭此行为,请将 @FeignClientprimary 属性设置为 false。

When using Feign with Spring Cloud CircuitBreaker fallbacks, there are multiple beans in the ApplicationContext of the same type. This will cause @Autowired to not work because there isn’t exactly one bean, or one marked as primary. To work around this, Spring Cloud OpenFeign marks all Feign instances as @Primary, so Spring Framework will know which bean to inject. In some cases, this may not be desirable. To turn off this behavior set the primary attribute of @FeignClient to false.

@FeignClient(name = "hello", primary = false)
public interface HelloClient {
	// methods here
}

Feign Inheritance Support

Feign 通过单继承接口支持样板 API。这使你可以将常见操作分组到方便的基本接口中。

Feign supports boilerplate apis via single-inheritance interfaces. This allows grouping common operations into convenient base interfaces.

UserService.java
public interface UserService {

	@GetMapping("/users/{id}")
	User getUser(@PathVariable("id") long id);
}
UserResource.java
@RestController
public class UserResource implements UserService {

}
UserClient.java
package project.user;

@FeignClient("users")
public interface UserClient extends UserService {

}

@FeignClient 接口不应在服务器和客户端之间共享,而且使用 @RequestMapping 在类级别注释 @FeignClient 接口也不再受支持。

@FeignClient interfaces should not be shared between server and client and annotating @FeignClient interfaces with @RequestMapping on class level is no longer supported.

[[feign-request/response-compression]]=== Feign 请求/响应压缩

[[feign-request/response-compression]] === Feign request/response compression

你可以考虑为 Feign 请求启用请求或响应 GZIP 压缩。你可以通过启用以下一个属性来实现此目的:

You may consider enabling the request or response GZIP compression for your Feign requests. You can do this by enabling one of the properties:

spring.cloud.openfeign.compression.request.enabled=true
spring.cloud.openfeign.compression.response.enabled=true

Feign 请求压缩提供的设置与你可以为 Web 服务器设置的设置类似:

Feign request compression gives you settings similar to what you may set for your web server:

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

这些属性使你可以有选择地指定压缩的媒体类型和最小请求阈值长度。

These properties allow you to be selective about the compressed media types and minimum request threshold length.

由于 OkHttpClient 使用“透明”压缩,当 content-encodingaccept-encoding 标头存在时禁用该压缩,当 classpath 上存在 feign.okhttp.OkHttpClient 并且 spring.cloud.openfeign.okhttp.enabled 被设为 true 时,我们不会启用压缩。

Since the OkHttpClient uses "transparent" compression, that is disabled if the content-encoding or accept-encoding header is present, we do not enable compression when feign.okhttp.OkHttpClient is present on the classpath and spring.cloud.openfeign.okhttp.enabled is set to true.

Feign logging

为创建的每个 Feign 客户端都会创建一个日志记录器。默认情况下,日志记录器的名称是用于创建 Feign 客户端的接口的全类名。Feign 日志记录只响应 DEBUG 级别。

A logger is created for each Feign client created. By default, the name of the logger is the full class name of the interface used to create the Feign client. Feign logging only responds to the DEBUG level.

application.yml
logging.level.project.user.UserClient: DEBUG

你可以针对每个客户端配置的 Logger.Level 对象会告知 Feign 记录的详细信息。选项包括:

The Logger.Level object that you may configure per client, tells Feign how much to log. Choices are:

  • NONE, No logging (DEFAULT).

  • BASIC, Log only the request method and URL and the response status code and execution time.

  • HEADERS, Log the basic information along with request and response headers.

  • FULL, Log the headers, body, and metadata for both requests and responses.

例如,下面的示例会将 Logger.Level 设置为 FULL

For example, the following would set the Logger.Level to FULL:

@Configuration
public class FooConfiguration {
	@Bean
	Logger.Level feignLoggerLevel() {
		return Logger.Level.FULL;
	}
}

Feign Capability support

Feign 功能公开了核心 Feign 组件,以便可以修改这些组件。例如,功能可以获取 Client、_decorate_它,并将装饰后的实例返回给 Feign。Micrometer 的支持就是此功能的出色实际示例。请参阅 Micrometer Support

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.

创建一或多个 Capability Bean 并将其置于 @FeignClient 配置中,这样可以注册这些 Bean 并修改所涉及客户端的行为。

Creating one or more Capability beans and placing them in a @FeignClient configuration lets you register them and modify the behavior of the involved client.

@Configuration
public class FooConfiguration {
	@Bean
	Capability customCapability() {
		return new CustomCapability();
	}
}

Micrometer Support

如果满足以下所有条件,则会创建一个 MicrometerObservationCapability Bean 并进行注册,以便你的 Feign 客户端可以由 Micrometer 观测:

If all of the following conditions are true, a MicrometerObservationCapability bean is created and registered so that your Feign client is observable by Micrometer:

  • feign-micrometer is on the classpath

  • A ObservationRegistry bean is available

  • feign micrometer properties are set to true (by default)

    • spring.cloud.openfeign.micrometer.enabled=true (for all clients)

    • spring.cloud.openfeign.client.config.feignName.micrometer.enabled=true (for a single client)

如果你的应用程序已经使用了 Micrometer,启用此功能只需将 feign-micrometer 放入你的 classpath 中即可。

If your application already uses Micrometer, enabling this feature is as simple as putting feign-micrometer onto your classpath.

你还可以通过以下方式禁用该功能:

You can also disable the feature by either:

  • excluding feign-micrometer from your classpath

  • setting one of the feign micrometer properties to false

    • spring.cloud.openfeign.micrometer.enabled=false

    • spring.cloud.openfeign.client.config.feignName.micrometer.enabled=false

spring.cloud.openfeign.micrometer.enabled=false 禁用 all Feign 客户端的 Micrometer 支持,无论客户端级别标志的值如何:spring.cloud.openfeign.client.config.feignName.micrometer.enabled。如果你想针对每个客户端启用或禁用 Micrometer 支持,请不要设置 spring.cloud.openfeign.micrometer.enabled 并使用 spring.cloud.openfeign.client.config.feignName.micrometer.enabled

spring.cloud.openfeign.micrometer.enabled=false disables Micrometer support for all Feign clients regardless of the value of the client-level flags: spring.cloud.openfeign.client.config.feignName.micrometer.enabled. If you want to enable or disable Micrometer support per client, don’t set spring.cloud.openfeign.micrometer.enabled and use spring.cloud.openfeign.client.config.feignName.micrometer.enabled.

你还可以通过注册自己的 Bean 来自定义 MicrometerObservationCapability

You can also customize the MicrometerObservationCapability by registering your own bean:

@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:

It is still possible to use MicrometerCapability with Feign (metrics-only support), you need to disable Micrometer support (spring.cloud.openfeign.micrometer.enabled=false) and create a MicrometerCapability bean:

@Configuration
public class FooConfiguration {
	@Bean
	public MicrometerCapability micrometerCapability(MeterRegistry meterRegistry) {
		return new MicrometerCapability(meterRegistry);
	}
}

Feign Caching

如果使用了 @EnableCaching 注解,则会创建并注册 CachingCapability Bean,以便你的 Feign 客户端可以识别其界面上的 @Cache 注解:

If @EnableCaching annotation is used, a CachingCapability bean is created and registered so that your Feign client recognizes @Cache* annotations on its interface:

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 禁用该功能。

You can also disable the feature via property spring.cloud.openfeign.cache.enabled=false.

Feign @QueryMap support

Spring Cloud OpenFeign 提供等效的 @SpringQueryMap 注释,用于将 POJO 或 Map 参数注释为查询参数映射。

Spring Cloud OpenFeign provides an equivalent @SpringQueryMap annotation, which is used to annotate a POJO or Map parameter as a query parameter map.

例如,Params 类定义参数 param1param2

For example, the Params class defines parameters param1 and param2:

// Params.java
public class Params {
	private String param1;
	private String param2;

	// [Getters and setters omitted for brevity]
}

以下 Feign 客户端使用 @SpringQueryMap 注释,来使用 Params 类:

The following feign client uses the Params class by using the @SpringQueryMap annotation:

@FeignClient("demo")
public interface DemoTemplate {

	@GetMapping(path = "/demo")
	String demoEndpoint(@SpringQueryMap Params params);
}

如果您需要更多控制生成的查询参数映射,则可以实现自定义 QueryMapEncoder Bean。

If you need more control over the generated query parameter map, you can implement a custom QueryMapEncoder bean.

HATEOAS support

Spring 提供了一些 API 来创建遵循 HATEOAS原则的 REST 表示: Spring HateoasSpring Data REST

Spring provides some APIs to create REST representations that follow the HATEOAS principle, Spring Hateoas and Spring Data REST.

如果您的项目使用 org.springframework.boot:spring-boot-starter-hateoas starter 或 org.springframework.boot:spring-boot-starter-data-rest starter,则默认启用 Feign HATEOAS 支持。

If your project use the org.springframework.boot:spring-boot-starter-hateoas starter or the org.springframework.boot:spring-boot-starter-data-rest starter, Feign HATEOAS support is enabled by default.

启用 HATEOAS 支持后,允许 Feign 客户端序列化和反序列化 HATEOAS 表示模型: EntityModelCollectionModelPagedModel

When HATEOAS support is enabled, Feign clients are allowed to serialize and deserialize HATEOAS representation models: EntityModel, CollectionModel and PagedModel.

@FeignClient("demo")
public interface DemoTemplate {

	@GetMapping(path = "/stores")
	CollectionModel<Store> getStores();
}

Spring @MatrixVariable Support

Spring Cloud OpenFeign 为 Spring @MatrixVariable 注释提供支持。

Spring Cloud OpenFeign provides support for the Spring @MatrixVariable annotation.

如果将映射作为方法参数传递,则通过使用 = 连接映射中的键值对来创建 @MatrixVariable 路径段。

If a map is passed as the method argument, the @MatrixVariable path segment is created by joining key-value pairs from the map with a =.

如果传递不同的对象,则使用 =@MatrixVariable 注释中提供的 name(如果已定义)或带注释的变量名称与提供的函数参数连接。

If a different object is passed, either the name provided in the @MatrixVariable annotation (if defined) or the annotated variable name is joined with the provided method argument using =.

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.

例如:

For example:

@GetMapping("/objects/links/{matrixVars}")
Map<String, List<String>> getObjects(@MatrixVariable Map<String, List<String>> matrixVars);

请注意,变量名称和路径段占位符都称为 matrixVars

Note that both variable name and the path segment placeholder are called matrixVars.

@FeignClient("demo")
public interface DemoTemplate {

	@GetMapping(path = "/stores")
	CollectionModel<Store> getStores();
}

Feign CollectionFormat support

通过提供 @CollectionFormat 注释,我们支持 feign.CollectionFormat。您可以通过将所需的 feign.CollectionFormat 作为注释值传递,用它注释 Feign 客户端方法(或整个类以影响所有方法)。

We support feign.CollectionFormat by providing the @CollectionFormat annotation. You can annotate a Feign client method (or the whole class to affect all methods) with it by passing the desired feign.CollectionFormat as annotation value.

在以下示例中,使用 CSV 格式来处理方法,而不是默认的 EXPLODED 格式。

In the following example, the CSV format is used instead of the default EXPLODED to process the method.

@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 也不支持。

As the OpenFeign project does not currently support reactive clients, such as Spring WebClient, neither does Spring Cloud OpenFeign.

由于 Spring Cloud OpenFeign 项目现在被认为已完成功能,因此即使它在上游项目中可用,我们也不计划添加支持。我们建议改为迁移到 Spring Interface Clients。它同时支持阻塞和响应式堆栈。

SinceSpring Cloud OpenFeign project is now considered feature-complete, we’re not planning on adding support even if it becomes available in the upstream project. We suggest migrating over to Spring Interface Clients instead. Both blocking and reactive stacks are supported there.

在完成之前,我们建议针对 Spring WebClient 支持使用 feign-reactive

Until that is done, we recommend using feign-reactive for Spring WebClient support.

Early Initialization Errors

我们不鼓励在应用程序生命周期的早期阶段(处理配置和初始化 Bean 时)使用 Feign 客户端。不支持在 Bean 初始化期间使用客户端。

We discourage using Feign clients in the early stages of application lifecycle, while processing configurations and initialising beans. Using the clients during bean initialisation is not supported.

同样,根据您使用 Feign 客户端的方式,您在启动应用程序时可能会看到初始化错误。要解决此问题,可以在自动装配客户端时使用 ObjectProvider

Similarly, depending on how you are using your Feign clients, you may see initialization errors when starting your application. To work around this problem you can use an ObjectProvider when autowiring your client.

@Autowired
ObjectProvider<TestFeignClient> testFeignClient;

Spring Data Support

如果类路径中存在 Jackson Databind 和 Spring Data Commons,将自动添加 org.springframework.data.domain.Pageorg.springframework.data.domain.Sort 的转换器。

If Jackson Databind and Spring Data Commons are on the classpath, converters for org.springframework.data.domain.Page and org.springframework.data.domain.Sort will be added automatically.

若要禁用此行为,请设置

To disable this behaviour set

spring.cloud.openfeign.autoconfiguration.jackson.enabled=false

有关详细信息,请参阅 org.springframework.cloud.openfeign.FeignAutoConfiguration.FeignJacksonConfiguration

See org.springframework.cloud.openfeign.FeignAutoConfiguration.FeignJacksonConfiguration for details.

Spring @RefreshScope Support

如果启用了 Feign 客户端刷新,则会使用以下内容创建每个 Feign 客户端:

If Feign client refresh is enabled, each Feign client is created with:

  • feign.Request.Options as a refresh-scoped bean. This means properties such as connectTimeout and readTimeout can be refreshed against any Feign client instance.

  • A url wrapped under org.springframework.cloud.openfeign.RefreshableUrl. This means the URL of Feign client, if defined with spring.cloud.openfeign.client.config.{feignName}.url property, can be refreshed against any Feign client instance.

您可以通过 POST /actuator/refresh 刷新这些属性。

You can refresh these properties through POST /actuator/refresh.

默认禁用 Feign 客户端中的刷新行为。使用以下属性启用刷新行为:

By default, refresh behavior in Feign clients is disabled. Use the following property to enable refresh behavior:

spring.cloud.openfeign.client.refresh-enabled=true

不要使用 @RefreshScope 注释注释 @FeignClient 接口。

DO NOT annotate the @FeignClient interface with the @RefreshScope annotation.

OAuth2 Support

通过将 spring-boot-starter-oauth2-client 依赖项添加到项目并设置以下标记,可以启用 OAuth2 支持:

OAuth2 support can be enabled by adding the spring-boot-starter-oauth2-client dependency to your project and setting following flag:

spring.cloud.openfeign.oauth2.enabled=true

当将该标记设置为 true 时,如果存在 oauth2 客户端上下文资源详细信息,则会创建一个 OAuth2AccessTokenInterceptor 类 bean。在每个请求之前,拦截器解析所需的访问令牌并将它包含为标头。OAuth2AccessTokenInterceptor 使用 OAuth2AuthorizedClientManager 获取包含 OAuth2AccessTokenOAuth2AuthorizedClient。如果用户使用 spring.cloud.openfeign.oauth2.clientRegistrationId 属性指定了 OAuth2 clientRegistrationId,则将使用该值来检索令牌。如果未检索令牌或未指定 clientRegistrationId,则将使用从 url 主机段检索到的 serviceId

When the flag is set to true, and the oauth2 client context resource details are present, a bean of class OAuth2AccessTokenInterceptor is created. Before each request, the interceptor resolves the required access token and includes it as a header. OAuth2AccessTokenInterceptor uses the OAuth2AuthorizedClientManager to get OAuth2AuthorizedClient that holds an OAuth2AccessToken. If the user has specified an OAuth2 clientRegistrationId using the spring.cloud.openfeign.oauth2.clientRegistrationId property, it will be used to retrieve the token. If the token is not retrieved or the clientRegistrationId has not been specified, the serviceId retrieved from the url host segment will be used.

TIP

Using the serviceId as OAuth2 client registrationId is convenient for load-balanced Feign clients. For non-load-balanced ones, the property-based clientRegistrationId 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 请求。

You can use the selected ServiceInstance to transform the load-balanced HTTP Request.

对于 Request,您需要按如下所示实现和定义 LoadBalancerFeignRequestTransformer

For Request, you need to implement and define LoadBalancerFeignRequestTransformer, as follows:

@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 来指定顺序。

If multiple transformers are defined, they are applied in the order in which beans are defined. Alternatively, you can use LoadBalancerFeignRequestTransformer.DEFAULT_ORDER to specify the order.

X-Forwarded Headers Support

可以通过设置以下标记来启用 X-Forwarded-HostX-Forwarded-Proto 的支持:

X-Forwarded-Host and X-Forwarded-Proto support can be enabled by setting following flag:

spring.cloud.loadbalancer.x-forwarded.enabled=true

Supported Ways To Provide URL To A Feign Client

您可以使用以下任何一种方式为 Feign 客户端提供 URL:

You can provide a URL to a Feign client in any of the following ways:

Case Example Details

The URL is provided in the @FeignClient annotation.

@FeignClient(name="testClient", url="http://localhost:8081")

The URL is resolved from the url attribute of the annotation, without load-balancing.

The URL is provided in the @FeignClient annotation and in the configuration properties.

@FeignClient(name="testClient", url="http://localhost:8081") and the property defined in application.yml as spring.cloud.openfeign.client.config.testClient.url=http://localhost:8081

The URL is resolved from the url attribute of the annotation, without load-balancing. The URL provided in the configuration properties remains unused.

The URL is not provided in the @FeignClient annotation but is provided in configuration properties.

@FeignClient(name="testClient") and the property defined in application.yml as spring.cloud.openfeign.client.config.testClient.url=http://localhost:8081

The URL is resolved from configuration properties, without load-balancing. If spring.cloud.openfeign.client.refresh-enabled=true, then the URL defined in configuration properties can be refreshed as described in spring-refreshscope-support.

The URL is neither provided in the @FeignClient annotation nor in configuration properties.

@FeignClient(name="testClient")

The URL is resolved from name attribute of annotation, with load balancing.

AOT and Native Image Support

Spring Cloud OpenFeign 支持 Spring AOT 转换和本地映像,但仅当禁用刷新模式、停用 Feign 客户端刷新(默认设置)和 xref:spring-cloud-openfeign.adoc#attribute-resolution-mode[lazy @FeignClient 属性分辨率(默认设置)时才支持。

Spring Cloud OpenFeign supports Spring AOT transformations and native images, however, only with refresh mode disabled, Feign clients refresh disabled (default setting) and lazy @FeignClient attribute resolution disabled (default setting).

如果你想在 AOT 或原生镜像模式下运行 Spring Cloud OpenFeign 客户端,请确保将 spring.cloud.refresh.enabled 设置为 false

If you want to run Spring Cloud OpenFeign clients in AOT or native image modes, make sure to set spring.cloud.refresh.enabled to false.

如果你想在 AOT 或原生镜像模式下运行 Spring Cloud OpenFeign 客户端,请确保未将 spring.cloud.openfeign.client.refresh-enabled 设置为 true

If you want to run Spring Cloud OpenFeign clients in AOT or native image modes, ensure spring.cloud.openfeign.client.refresh-enabled has not been set to true.

如果你想在 AOT 或原生镜像模式下运行 Spring Cloud OpenFeign 客户端,请确保未将 spring.cloud.openfeign.lazy-attributes-resolution 设置为 true

If you want to run Spring Cloud OpenFeign clients in AOT or native image modes, ensure spring.cloud.openfeign.lazy-attributes-resolution has not been set to true.

不过,如果你通过属性设置 url 值,则可以通过使用 -Dspring.cloud.openfeign.client.config.[clientId].url=[url] 标志运行镜像来覆盖 @FeignClient url 值。为了启用覆盖,还必须通过属性而非在构建期间时的 @FeignClient 属性设置 url 值。

However, if you set the url value via properties, it is possible to override the @FeignClient url value by running the image with -Dspring.cloud.openfeign.client.config.[clientId].url=[url] flag. In order to enable overriding, a url value also has to be set via properties and not @FeignClient attribute during buildtime.

Configuration properties

要查看所有 Spring Cloud OpenFeign 相关配置属性的列表,请查看 the Appendix page

To see the list of all Spring Cloud OpenFeign related configuration properties please check the Appendix page.