Spring 启动器 - RestTemplate

Spring Boot starter - RestTemplate

我目前正在尝试编写一个 Spring 引导启动程序,它将自动使用 API 网关验证我们的微服务,并在 headers 中包含所有传出请求的访问令牌(朝向网关)。
我正在创建一个 RestTemplate bean 并为其提供我们的自定义拦截器,但我的问题是,通过这样做,我阻止了其他团队(将使用此 starter)使用他们自己的 RestTemplate 配置,因为他们会必须定义导致存在多个 bean 的相同 bean。

@Bean
public RestTemplate restTemplate(){
  RestTemplate restTemplate = new RestTemplate();
  List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
  if (interceptors.isEmpty()){
    interceptors = new ArrayList<>();
  }
  interceptors.add(clientCredentialsAuthInterceptor());
  restTemplate.setInterceptors(interceptors);
  return restTemplate;
}

是否有另一种方法可以拦截所有传出请求或使 RestTemplate 进一步可配置?

未经测试,但它可能会给您一个起点:

// Create an interface that users of your dependency 
// can implement which provides interceptors
public interface RestTemplateAuthInterceptorProvider {

  // This interface provides interceptors, so they can add as many as they want
  List<ClientHttpRequestInterceptor> provideInterceptor();
}

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
// define a conditional default implementation of your interceptor provider
@Bean
@ConditionalOnMissingBean(RestTemplateAuthInterceptorProvider.class)
public RestTemplateAuthInterceptorProvider restTemplateAuthInterceptorProvider() {
  return () -> ... // implement your auth interceptor and return
}

// In your actual rest template creation use method argument injection
// If other teams implement the RestTemplateAuthInterceptorProvider interface
// conditional case above will be false and your implementation will not interfere
// If they dont implement RestTemplateAuthInterceptorProvider
// your default implementation will be here
@Bean
public RestTemplate restTemplate(RestTemplateAuthInterceptorProvider provider) {
  RestTemplate restTemplate = new RestTemplate();
  List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
  if (interceptors == null){
    interceptors = new ArrayList<>();
  }
  interceptors.addAll(provider.provideInterceptor()); // from argument 
  restTemplate.setInterceptors(interceptors);
  return restTemplate;
}

编辑: 另一种 hacky 方法是操作已经定义的 RestTemplate bean

@Component
@ConditionalOnBean(RestTemplate.class)
public class RestTemplateBeanCustomizer {

  private List<RestTemplate> restTemplateBeans;

  // This injects all restTemplate bean definitions to your bean as a list
  @Autowired
  public RestTemplateBeanCustomizer(List<RestTemplate> restTemplateBeans) {
    this.restTemplateBeans = restTemplateBeans;
  }

  @PostConstruct
  public void customizeRestTemplateBeans() {
      for (RestTemplate restTemplate : restTemplateBeans) {
        // Add your interceptors message handlers etc
        // restTemplate.set...
      }
  }
}