Summary of Spring Cloud OpenFeign knowledge points

1. Declarative REST client: Feign

Feign is a declarative Web Service client. It makes writing web service clients easier. To use Feign, you need to 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 supports the use of HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Eureka, Spring Cloud CircuitBreaker and Spring Cloud LoadBalancer to provide a load-balanced http client when using Feign.

1.1. How to "include" Feign

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 building the system with the current Spring Cloud Release Train setup.

Example: Spring Boot application

@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();

    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    Page<Store> getStores(Pageable pageable);

    @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
    Store update(@PathVariable("storeId") Long storeId, Store store);

    @RequestMapping(method = RequestMethod.DELETE, value = "/stores/{storeId:\\d+}")
    void delete(@PathVariable Long storeId);
}

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

The load balancer client above will want to discover the physical address of 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 use SimpleDiscoveryClient to configure a list of services in your external configuration.

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

To use the @EnableFeignClients annotation on a @Configuration annotated class, make sure to specify the location of the clients, eg: @EnableFeignClients(basePackages = "com.example.clients") or list them explicitly: @EnableFeignClients(clients = InventoryServiceFeignClient.class)

1.1.1. Attribute resolution mode

When creating a Feign client bean, we resolve the passed value through the @FeignClient annotation. Starting with 4.x, these values ​​are parsed eagerly. This is a good solution for most use cases, and it also allows for AOT support.

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

For Spring Cloud Contract test integrations, lazy property resolution should be used.

1.2. Overriding Feign's defaults

A core concept in Spring Cloud's Feign support is named clients. Each feign client is part of a collection of components that work together to contact remote servers on demand, and that collection has a name that you, the application developer, give it with the @FeignClient annotation. Spring Cloud uses FeignClientsConfiguration to create a new composition as ApplicationContext on demand for each named client. This includes (among other things) a feign.Decoder, a feign.Encoder and a feign.Contract. The collection's name can be overridden by using the contextId attribute of the @FeignClient annotation.

Spring Cloud gives you full control over the feign client by using @FeignClient to declare additional configuration (on top of FeignClientsConfiguration). example:

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

In this case client consists of components already in FeignClientsConfiguration and any components in FooConfiguration (the latter will override the former).

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 be the default source for feign.Decoder, feign.Encoder, feign.Contract, etc. This can be avoided by placing it in a separate, non-overlapping package from any @ComponentScan or @SpringBootApplication, or explicitly excluding it in @ComponentScan.

Using the contextId attribute of the @FeignClient annotation, in addition to changing the name of the ApplicationContext collection, it will also override the alias of the client name, which will be used as part of the name of the configuration bean created by the client.

Previously, using the url attribute, there was no need to use the name attribute. Now, using name is mandatory.

Placeholders are supported in the name and url attributes.

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

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

  • Decoder feignDecoder: ResponseEntityDecoder (it encapsulates 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 the @EnableCaching annotation is used, it can be disabled by spring.cloud.openfeign.cache.enabled.
  • Contract feignContract: SpringMvcContract
  • Feign.Builder feignBuilder: FeignCircuitBreaker.Builder
  • Client feignClient: FeignBlockingLoadBalancerClient will be used if Spring Cloud LoadBalancer is on the classpath. If neither is on the classpath, the default feign client is used.

spring-cloud-starter-openfeign supports spring-cloud-starter-loadbalancer. However, since it's an optional dependency, you'll need to make sure it's added to your project if you want to use it.

The OkHttpClient and Apache HttpClient 5 Feign clients can be used by setting spring.cloud.openfeign.okhttp.enabled or spring.cloud.openfeign.httpclient.hc5.enabled respectively to true and putting them on the classpath. When using Apache HC5, you can customize the HTTP client used by providing a bean of org.apache.hc.client5.http.impl.classic.CloseableHttpClient.

You can further customize the http client by setting values ​​in the spring.cloud.openfeign.httpclient.xxx properties. Only properties prefixed with httpclient will apply to all clients, properties prefixed with httpclient.hc5 will apply to Apache HttpClient 5, and properties prefixed with httpclient.okhttp will apply to OkHttpClient. You can find a full list of properties you can customize in the appendix.

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

Spring Cloud OpenFeign does not provide feign with the following beans by default, but still finds these types of beans from the application context to create feign clients:

  • Logger.Level
  • Retryer
  • ErrorDecoder
  • Request.Options
  • Collection<RequestInterceptor>
  • SetterFactory
  • QueryMapEncoder
  • Capability (MicrometerObservationCapability and CachingCapability provided by default) By default, a Retryer bean of type Retryer.NEVER_RETRY is created, which disables retries. Note that this retry behavior differs from Feign's default behavior, which will automatically retry IOExceptions, treating them as transient network-related exceptions, as well as any RetryableException thrown from the ErrorDecoder.

Creating a bean of these types and placing it in a @FeignClient configuration (like FooConfiguration above) allows you to override each bean as described. example:

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

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

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

@FeignClient can also 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

The feignName in this example refers to the @FeignClient value, which is also aliased to @FeignClient name and @FeignClient contextId. In the case of load balancing, it also corresponds to the serviceId of the server application that will be used to retrieve the instance.

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

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

You can use spring.cloud.openfeign.client.config.feignName.defaultQueryParameters and spring.cloud.openfeign.client.config.feignName.defaultRequestHeaders to specify query parameters and header information, which will be associated with each request of the client named feignName send together.

application.yml

spring:
    cloud:
        openfeign:
            client:
                config:
                    default:
                        connectTimeout: 5000
                        readTimeout: 5000
                        loggerLevel: basic

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

If we want to create multiple feign clients with the same name or url pointing to the same server, but each with a different custom configuration, then we must use the contextId attribute of @FeignClient to avoid the Name conflict.

@FeignClient(contextId = "fooClient", name = "stores", configuration = FooConfiguration.class)
public interface FooClient {
    //..
}
@FeignClient(contextId = "barClient", name = "stores", configuration = BarConfiguration.class)
public interface BarClient {
    //..
}

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

@Configuration
public class CustomConfiguration{

@Bean
public FeignClientConfigurer feignClientConfigurer() {
            return new FeignClientConfigurer() {

                @Override
                public boolean inheritParentConfiguration() {
                    return false;
                }
            };

        }
}

By default, Feign client does not encode slashes/characters. You can change this behavior by setting the value of spring.cloud.openfeign.client.decodeSlash to false.

1.2.1. Spring Encoder configuration

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

You can modify this behavior by setting the value of spring.cloud.openfeign.encoder.charset-from-content-type to true so that the charset is deduced from the characters in the Content-Type header.

1.3. Timeout processing

We can configure timeouts on both default and named clients. OpenFeign uses two timeout parameters:

  • connectTimeout prevents the caller from blocking due to server processing taking too long.
  • The readTimeout is applied from connection establishment and is fired when it takes too long to return a response.

If the server is not running or available, the packet causes the connection to be refused. Communication ends with an error message or fallback. This may happen before it if connectTimeout is set low. A significant portion of this delay is caused by the time it takes to perform the lookup and receive such a packet. It may change depending on the remote host involved in the DNS query.

1.4. Manually create Feign Client

In some cases, it may be necessary to make customizations to your Feign client that are not possible using the methods described above. In this case, you can use the Feign Builder API to create the client. Here's an example that creates two Feign clients with the same interface, but each configured 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");
    }
}

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

PROD-SVC is the name of the service to which the client will make the request.

The Feign Contract object defines which annotations and values ​​are valid for the interface. The automatically injected Contract Bean provides support for SpringMVC annotations instead of the default Feign native annotations.

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

1.5. Feign Spring Cloud CircuitBreaker support

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

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

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

Circuit breaker names follow the pattern <feignClientClassName>#<calledMethod>(<parameterTypes>). When calling a @FeignClient with a FooClient interface, and the called interface method bar has no parameters, the name of the circuit breaker will be FooClient#bar().

Starting from 2020.0.2, the circuit breaker name pattern has changed from <feignClientName>_<calledMethod>. With the CircuitBreakerNameResolver introduced in 2020.0.4, circuit breaker names can remain in the old schema.

By providing a CircuitBreakerNameResolver bean, 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();
    }
}

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

1.6. Configuring CircuitBreaker using configuration properties

You can configure CircuitBreaker through configuration properties.

For example, if you have this Feign client

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

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

You can configure it using configuration properties in the following way

spring:
  cloud:
    openfeign:
      circuitbreaker:
        enabled: true
        alphanumeric-ids:
          enabled: true
resilience4j:
  circuitbreaker:
    instances:
      DemoClientgetDemo:
        minimumNumberOfCalls: 69
  timelimiter:
    instances:
      DemoClientgetDemo:
        timeoutDuration: 10s

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

1.7. Feign Spring Cloud CircuitBreaker Fallback

Spring Cloud CircuitBreaker supports the concept of fallback: a default code path that is executed when the circuit is opened or an error occurs. To enable fallback for a given @FeignClient, set the fallback attribute to the name of the class implementing 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 {

        @RequestMapping(method = RequestMethod.GET, value = "/hello")
        Hello getHello();

        @RequestMapping(method = RequestMethod.GET, value = "/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";
        }

    }

If you need to access what caused the fallback to fire, you can use the fallbackFactory attribute in @FeignClient.

@FeignClient(name = "testClientWithFactory", url = "http://localhost:${server.port}/",
            fallbackFactory = TestFallbackFactory.class)
    protected interface TestClientWithFactory {

        @RequestMapping(method = RequestMethod.GET, value = "/hello")
        Hello getHello();

        @RequestMapping(method = RequestMethod.GET, value = "/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";
        }

    }

1.8. Feign and @Primary

When using Feign with Spring Cloud CircuitBreaker fallback, there are multiple beans of the same type in the ApplicationContext. This will cause @Autowired to not work because there is not exactly one bean, or one marked as primary. To solve 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
}

1.9. Support for Feign inheritance

Feign supports template-style APIs through single-inheritance interfaces. This allows grouping of common operations into a convenient base interface.

UserService.java

public interface UserService {

    @RequestMapping(method = RequestMethod.GET, value ="/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 interfaces should not be shared between server and client, and annotating @FeignClient interfaces with @RequestMapping at the class level is no longer supported.

1.10. Feign request/response compression

You might consider enabling GZIP compression of requests or responses for your Feign requests. You can do this by enabling one of these properties:

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

Feign request compression gives you settings similar to what you might have 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 choose between compressed media types and minimum request threshold lengths.

Since OkHttpClient uses "transparent" compression, which is disabled in the presence of content-encoding or accept-encoding headers, when feign.okhttp.OkHttpClient is present on the classpath and spring.cloud.openfeign.okhttp.enabled is set When true, we don't enable compression.

1.11. Feign logs

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

application.yml

logging.level.project.user.UserClient: DEBUG

You can configure a Logger.Level object per client to tell Feign how much to log. The choices are:

  • NONE, no logging ( default ).
  • BASIC, only logs the request method and URL along with the response status code and execution time.
  • HEADERS, records basic information and request and response headers.
  • FULL, logs request and response headers, body and metadata.

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

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

1.12. Feign Capability support

Feign Capability exposes Feign's core components so they can be modified. For example, these functions can accept a client, decorate it, and feed the decorated instance back to Feign. Support for Micrometer is a good real-life example. See [micrometer-support].

Creating one or more Capability Beans and placing them in a @FeignClient configuration allows you to register them and modify the behavior of the associated client.

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

1.13. Micrometer support

A MicrometerObservationCapability Bean is created and registered so that your Feign client can be observed by Micrometer if all of the following conditions are true:

  • feign-micrometer is on the classpath.
  • The ObservationRegistry bean is available.
  • feign micrometer property set to true (default)
    • spring.cloud.openfeign.micrometer.enabled=true (for all clients)
    • spring.cloud.openfeign.client.config.feignName.micrometer.enabled=true (for a single client)

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

You can also disable this feature in two ways:

  • Exclude feign-micrometer from your classpath.
  • Set feign micrometer one property to false
    • spring.cloud.openfeign.micrometer.enabled=false
    • spring.cloud.openfeign.client.config.feignName.micrometer.enabled=false

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

You can also customize MicrometerObservationCapability by registering your own bean:

@Configuration
public class FooConfiguration {
    @Bean
    public MicrometerObservationCapability micrometerObservationCapability(ObservationRegistry registry) {
        return new MicrometerObservationCapability(registry);
    }
}

It is still possible to use MicrometerCapability in Feign (only metrics are supported), 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);
    }
}

1.14. Feign caching

If the @EnableCaching annotation is used, a CachingCapability Bean will be created and registered so that your Feign client will recognize the @Cache* annotation on its interface:

public interface DemoClient {

    @GetMapping("/demo/{filterParam}")
    @Cacheable(cacheNames = "demo-cache", key = "#keyParam")
    String demoEndpoint(String keyParam, @PathVariable String filterParam);
}

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

1.15. Feign @QueryMap support

Spring Cloud OpenFeign provides an equivalent @SpringQueryMap annotation for annotating POJO or Map parameters as query parameter maps.

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

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

    // [Getters and setters omitted for brevity]
}

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

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

1.16. HATEOAS support

Spring provides APIs to create REST representations following the HATEOAS principles, Spring Hateoas and Spring Data REST.

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

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();
}

1.17. Spring @MatrixVariable support

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

If a map is passed as a method parameter, the @MatrixVariable path segment is created by concatenating the key-value pairs in the map with =.

If a different object is passed, the name provided in the @MatrixVariable annotation (if defined) or the annotated variable name will be combined using = with the provided method parameter.

IMPORTANT

Although on the server side, Spring does not require the user to name the path segment placeholder the same as the matrix variable, as this would be too ambiguous on the client side, Spring Cloud OpenFeign requires you to add a path segment placeholder with the name Matches 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);

Note that both variable names and path segment placeholders are called matrixVars.

@FeignClient("demo")
public interface DemoTemplate {

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

1.18. FeignCollectionFormat support

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

In the example below, the CSV format is used instead of the default EXPLODED for this method.

@FeignClient(name = "demo")
protected interface DemoFeignClient {

    @CollectionFormat(feign.CollectionFormat.CSV)
    @GetMapping(path = "/test")
    ResponseEntity performRequest(String test);

}

1.19. Reactive support

Since the OpenFeign project does not currently support reactive clients such as Spring WebClient, neither does Spring Cloud OpenFeign. We will add support for it here once it is available in the core project.

Until then, we recommend using feign-reactive to support Spring WebClient.

1.19.1. Early initialization errors

Depending on how you use the Feign client, you may see initialization errors when starting your application. To solve this problem, you can use an ObjectProvider when autoconnecting clients.

@Autowired
ObjectProvider<TestFeignClient> testFeignClient;

1.20. Spring Data support

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

To disable this behavior, set:

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

详见 org.springframework.cloud.openfeign.FeignAutoConfiguration.FeignJacksonConfiguration。

1.21. Spring @RefreshScope support

If Feign client refresh is enabled, every Feign client creation has:

  • feign.Request.Options as a refresh scope bean. This means properties such as connectTimeout and readTimeout can be refreshed for any Feign client instance.
  • The url wrapped under org.springframework.cloud.openfeign.RefreshableUrl. This means that if you define the Feign client URL with the spring.cloud.openfeign.client.config.{feignName}.url property, you can refresh against any Feign client instance.

You can refresh these attributes via POST /actuator/refresh.

By default, the Feign client's refresh behavior is disabled. Use the following properties to enable refresh behavior:

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

Do not annotate @FeignClient interface with @RefreshScope annotation.

1.22. OAuth2 support

OAuth2 support can be enabled by setting the following flag:

spring.cloud.openfeign.oauth2.enabled=true

When this flag is set to "true" and the oauth2 client context resource detail exists, a bean of class OAuth2AccessTokenInterceptor is created. Before each request, the interceptor parses the required access token and presents it as a header. OAuth2AccessTokenInterceptor uses OAuth2AuthorizedClientManager to obtain OAuth2AuthorizedClient holding OAuth2AccessToken. If the user specifies an OAuth2 clientRegistrationId using the spring.cloud.openfeign.oauth2.clientRegistrationId property, it will be used to retrieve the token. If no token is retrieved or clientRegistrationId is not specified, the serviceId retrieved from the url host segment will be used.

TIP

Using the serviceId as the registrationId of the OAuth2 client is convenient for load-balanced Feign clients. For non-load-balanced clients, the property-based clientRegistrationId is an appropriate approach.

TIP

If you don't want to use the default OAuth2AuthorizedClientManager, you can instantiate a bean of this type directly in your configuration.

1.23. Transform load-balanced HTTP requests

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

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());
        }
    };
}

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

1.24. Support for X-Forwarded Headers

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

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

1.25. Support methods for providing URLs to Feign clients

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

Scenes

example

detail

The URL is provided in the @FeignClient annotation.

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

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

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

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

The URL is parsed from the url attribute of the annotation, without load balancing. The URL provided in the configuration property is still not used.

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,那么配置属性中定义的 URL 可以被刷新,如 Spring RefreshScope 的支持 中所述。

在 @FeignClient 注解中和配置属性中都没有提供这个URL。

@FeignClient(name="testClient")

URL是从注解的 name 属性中解析出来的,具有负载均衡性。

1.26. AOT 和原生镜像的支持

Spring Cloud OpenFeign 支持 Spring AOT 转换和原生镜像,但是,只有在禁用刷新模式、禁用Feign客户端刷新(默认设置)和禁用 延迟的 @FeignClient 属性解析(默认设置)的情况下,才能支持。

如果你想在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 值。为了实现覆盖,在构建时也必须通过属性而不是 @FeignClient 属性来设置一个 url 值。

2. 配置属性

各种属性可以在 application.properties 文件、application.yml 文件中指定,也可以作为命令行开关。本附录提供了一个常见的 Spring Cloud OpenFeign 属性列表,以及对消费这些属性的底层类的引用。

属性贡献可以来自你classpath上的其他jar文件,所以你不应该认为这是一个详尽的列表。另外,你可以定义你自己的属性。
Name Default Description

spring.cloud.openfeign.autoconfiguration.jackson.enabled

false

If true, PageJacksonModule and SortJacksonModule bean will be provided for Jackson page decoding.

spring.cloud.openfeign.circuitbreaker.enabled

false

If true, an OpenFeign client will be wrapped with a Spring Cloud CircuitBreaker circuit breaker.

spring.cloud.openfeign.circuitbreaker.group.enabled

false

If true, an OpenFeign client will be wrapped with a Spring Cloud CircuitBreaker circuit breaker with with group.

spring.cloud.openfeign.client.config

spring.cloud.openfeign.client.decode-slash

true

Feign clients do not encode slash / characters by default. To change this behavior, set the decodeSlash to false.

spring.cloud.openfeign.client.default-config

default

spring.cloud.openfeign.client.default-to-properties

true

spring.cloud.openfeign.client.refresh-enabled

false

Enables options value refresh capability for Feign.

spring.cloud.openfeign.compression.request.enabled

false

Enables the request sent by Feign to be compressed.

spring.cloud.openfeign.compression.request.mime-types

[text/xml, application/xml, application/json]

The list of supported mime types.

spring.cloud.openfeign.compression.request.min-request-size

2048

The minimum threshold content size.

spring.cloud.openfeign.compression.response.enabled

false

Enables the response from Feign to be compressed.

spring.cloud.openfeign.encoder.charset-from-content-type

false

Indicates whether the charset should be derived from the {@code Content-Type} header.

spring.cloud.openfeign.httpclient.connection-timeout

2000

spring.cloud.openfeign.httpclient.connection-timer-repeat

3000

spring.cloud.openfeign.httpclient.disable-ssl-validation

false

spring.cloud.openfeign.httpclient.enabled

true

Enables the use of the Apache HTTP Client by Feign.

spring.cloud.openfeign.httpclient.follow-redirects

true

spring.cloud.openfeign.httpclient.hc5.enabled

false

Enables the use of the Apache HTTP Client 5 by Feign.

spring.cloud.openfeign.httpclient.hc5.pool-concurrency-policy

Pool concurrency policies.

spring.cloud.openfeign.httpclient.hc5.pool-reuse-policy

Pool connection re-use policies.

spring.cloud.openfeign.httpclient.hc5.socket-timeout

5

Default value for socket timeout.

spring.cloud.openfeign.httpclient.hc5.socket-timeout-unit

Default value for socket timeout unit.

spring.cloud.openfeign.httpclient.max-connections

200

spring.cloud.openfeign.httpclient.max-connections-per-route

50

spring.cloud.openfeign.httpclient.ok-http.read-timeout

60s

{@link OkHttpClient} read timeout; defaults to 60 seconds.

spring.cloud.openfeign.httpclient.time-to-live

900

spring.cloud.openfeign.httpclient.time-to-live-unit

spring.cloud.openfeign.micrometer.enabled

true

Enables Micrometer capabilities for Feign.

spring.cloud.openfeign.oauth2.enabled

false

Enables feign interceptor for managing oauth2 access token.

spring.cloud.openfeign.oauth2.load-balanced

false

Enables load balancing for oauth2 access token provider.

spring.cloud.openfeign.okhttp.enabled

false

Enables the use of the OK HTTP Client by Feign.

Guess you like

Origin blog.csdn.net/leesinbad/article/details/131991170