Стартер Spring Boot — RestTemplate

В настоящее время я пытаюсь написать стартер Spring Boot, который автоматически аутентифицирует наши микросервисы с помощью шлюза API и включает токен доступа в заголовки для всех исходящих запросов (к шлюзу).
Я создаю bean-компонент RestTemplate и даю ему наш пользовательский перехватчик, но моя проблема в том, что, делая это, я не позволяю другим командам (которые будут использовать этот стартер) использовать свою собственную конфигурацию 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?

В идеале ваши проекты должны использовать RestTemplateBuilder для создания экземпляров RestTEmplate, это, в свою очередь, автоматически обнаружит все предварительно зарегистрированные перехватчики. Единственное, что должен сделать ваш autp-config, это создать bean-компонент для перехватчика. Или определите RestTemplateCustomizer, который добавляет перехватчик. Однако это работает только в том случае, если команды следуют практике использования RestTemplateBuilder для создания экземпляров.

M. Deinum 10.12.2020 16:39
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
332
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Не проверено, но может дать вам отправную точку:

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

Редактировать: Другой хакерский подход заключается в манипулировании уже определенными bean-компонентами RestTemplate.

@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...
      }
  }
}

Это только позволит им определить свои собственные перехватчики, если я прав. Мой вопрос больше касается создания самого RestTemplate. Допустим, они хотят добавить к нему собственный messageHandler, но стартер уже определил bean-компонент без этого. Я мог бы аннотировать его с помощью @ConditionalOnMissingBean, но тогда, если кто-то его определит, у него не будет установлен перехватчик.

Iamtazy 10.12.2020 16:31

Другие вопросы по теме