如何在每个 class WebClient 重试时避免硬编码

How to avoid hardcode in every class WebClient retryWhen

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

  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();
  }

但我想创建一个通用的,以便在所有应用程序中使用它,而不是全部编写第一个方法类,我怎样才能更有效地做到这一点?

我会在配置 class 中将 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)