Search code examples
spring-bootfeign

Why does the Feign client custom configuration structure not meet this way?


I am using feign client in an application with spring boot version 3.1.4

I made a configuration definition for the feign client.

Configuration class

@Configuration
@RequiredArgsConstructor
public class FeignConfiguration {

  
   @Bean
   public Decoder feignDecoder(ObjectFactory<HttpMessageConverters> messageConverters) 
   {
      //bla bla
   }

   @Bean
   public RequestInterceptor requestInterceptor() {
      //bla bla
   }

}

Feign Client

@FeignClient(name = "", url = "")
public interface FeignClient {
   //some methods
}

If I define it as above, it can find the relevant configurations without defining the configuration. However, I want to define a new feign client and I want this to be a new configuration. I am writing a second feign configuration class for this.

Second Configuration class

@Configuration
@RequiredArgsConstructor
public class SecondFeignConfiguration {

  
   @Bean
   public Decoder feignDecoder(ObjectFactory<HttpMessageConverters> messageConverters) 
   {
      //bla bla
   }

   @Bean
   public RequestInterceptor requestInterceptor() {
      //bla bla
   }

}

Second Feign Client

@FeignClient(name = "", url = "", configuration = SecondFeignConfiguration.class)
public interface SecondFeignClient {
   //some methods
}

While I'm waiting for my second feign client requests to work based on the configuration I gave, the feign configuration works based on the configuration (the one I defined first).

In the configurations I made for Feign client If I do not use the @Configuration annotation, it works as I want and I have to specify configuration = "...configuration" for all feign clients I use.

Why does it happen this way?


Solution

  • According to the documentation:

    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.

    That means that Spring dynamically creates a separate ApplicationContext for each Feign client, which allows isolation between them. By declaring configuration using the @FeignClient annotation, you are telling Spring to use that configuration inside the ApplicationContext of that particular client. For that reason, it does not need to be annotated with @Configuration. However, if it is, it will become the default source for feign.Decoder, feign.Encoder, etc., when specified.

    To conclude, use @Configuration on the class containing the default beans of feign.Decoder, feign.Encoder, etc. When there is a need for specific beans, create a separate class, without @Configuration, containing the beans that would override the default ones and declare it as the configuration in the @FeignClient annotation.