如何避免每个类中的硬编码WebClient重试时间

问题描述

我想实现重试机制,我做了这样的事情:

  public static final Retry fixedRetry = Retry.fixedDelay(3,Duration.ofSeconds(5))
      .onRetryExhaustedThrow(
          (retryBackoffSpec,retrySignal) -> new TimeoutException(
              retrySignal.failure().getMessage()));

并在此使用此方法

 public List<A> findByTimestamp(LocalDate localDate) {
    return webClient.get()
        .uri(bProp.getPath())
        .header(HttpHeaders.ACCEPT,MediaType.APPLICATION_JSON_VALUE)
        .retrieve()
        .bodyToFlux(bData.class)
        .retrywhen(fixedRetry)
        .map(this::toC)
        .collectList()
        .block();
  }

但是我想创建一个通用的类,以便在所有应用程序中使用它,而不是在所有类中都编写第一个方法,我该如何更有效地做到这一点?

解决方法

我将在一个配置类中将webClient注册为Bean,并在其中实现重试逻辑,然后在需要webClient的地方对其进行自动装配,而不是显式创建一个新对象。我找到了一个对similiar question可能有用的答案。

我没有时间检查这段代码是否有效,但是我的意思是:

@Configuration
public class WebClientConfiguration {

@Bean
public WebClient retryWebClient(WebClient.Builder builder) {
    return builder.baseUrl("http://localhost:8080")
            .filter((request,next) -> next.exchange(request)
                    .retryWhen(Retry.fixedDelay(3,Duration.ofSeconds(5))
                            .onRetryExhaustedThrow(
                                    (retryBackoffSpec,retrySignal) -> new TimeoutException(
                                            retrySignal.failure().getMessage()))))
            .build();
}
}

然后将其自动接线到所需的任何地方:

@Autowired
private WebClient webClient;
,

我决定实现此目标的方式如下:

public class RetryWebClient {

  public static final Retry fixedRetry = Retry.fixedDelay(3,Duration.ofSeconds(5))
      .onRetryExhaustedThrow(
          (retryBackoffSpec,retrySignal) -> new TimeoutException(
              retrySignal.failure().getMessage()));

  private RetryWebClient() {}

}

并在retryWhen中调用它:

.retryWhen(RetryWebClient.fixedRetry)