“全局”Feign 拦截器并未被所有 Feign 客户端采用

jav*_*pie 5 java spring-boot spring-cloud-feign

我们在应用程序中使用 Open Feign,该应用程序在 Spring Boot 2.0.6 和 Spring Cloud Finchley.SR2 上运行。

我们需要所有 Feign 客户端在每次调用的标头中添加来自安全上下文的令牌,因此我们创建了一个配置,它为所有客户端生成一个全局拦截器:

@Configuration
@Import({FeignClientsConfiguration.class})
public class FeignConfig {

   @Value("${a.spring.config}")
   private int minTokenLifespan;

   @Autowired
   private OAuthContext oAuthContext;

   @Autowired
   private AuthManager authManager;

   @Bean
   public RequestInterceptor myCustomInterceptor() {
       return new CustomInterceptor(oAuthContext, authManager, minTokenLifespan);
   }
}
Run Code Online (Sandbox Code Playgroud)

该拦截器适用于除一个之外的所有 Feign 客户端。在调试器中我们可以看到,在类中创建 Bean之前,创建了这个特殊的 feign 客户端(及其 SynchronousMessageHandler)FeignConfig。仅在第一个 Feign 客户端之后创建CustomIntercepter,所有其他客户端都是在之后创建的,知道拦截器的存在并将应用它。

我们该如何调试这个问题呢?过去有人遇到过不同的问题吗?

我无法发布生产代码,但我很乐意回答任何问题并尝试发布混淆的代码。

an3*_*0na 7

这表明在创建第一个客户端时创建拦截器存在问题。

尝试在org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeansOfType上放置一个条件断点RequestInterceptor.classFeignConfig您可能会发现存在循环依赖关系,它要求在实例化或类之前创建第一个客户端CustomInterceptor

考虑以下示例:

@Configuration
@EnableFeignClients(
  clients = {
    MyFirstClient.class, // will NOT have CustomInterceptor registered
    MySecondClient.class // will have CustomInterceptor registered
  })
public class FeignConfig {

  @Autowired
  private BeanDependentOnMyFirstClient beanDependentOnMyFirstClient;

  @Bean
  public RequestInterceptor myCustomInterceptor() {
    return new CustomInterceptor();
  }
}
Run Code Online (Sandbox Code Playgroud)

这将导致以下循环依赖:

在此输入图像描述

由于客户端和拦截器之间的依赖关系很弱,如果不能满足依赖关系,拦截器就会默默地失败。