问题描述
我想实现重试机制,我做了这样的事情:
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)