本来想给RestTemplate加个重试机制,下面是代码:
@Component
@Slf4j
public class EcGoodsManagerImpl implements IEcGoodsManager {
private RestTemplate restTemplate;
@Autowired
public EcGoodsManagerImpl(RestTemplateBuilder builder) {
HttpClientBuilder clientBuilder = HttpClients.custom();
clientBuilder.setRetryHandler((exception, executionCount, httpContext) -> {
if (executionCount > 3) {
log.info("重试次数超过3次");
return false;
}
if (exception instanceof NoHttpResponseException || exception instanceof SocketException) {
log.info("服务器无响应,重试次数:" + executionCount);
return true;
}
return false;
});
CloseableHttpClient httpClient = clientBuilder.build();
HttpComponentsClientHttpRequestFactory httpComponentsClientHttpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
builder.requestFactory(() -> httpComponentsClientHttpRequestFactory);
restTemplate = builder.build();
}
}
后来发现重试机制不生效,debug发现没有用上面定义的RetryHandler
经过排查发现,是以下代码有问题
builder.requestFactory(() -> httpComponentsClientHttpRequestFactory);
restTemplate = builder.build();
builder.requestFactory(() -> httpComponentsClientHttpRequestFactory)
这个方法,查看源码,才知道会返回一个新的Builder
public RestTemplateBuilder requestFactory(Supplier<ClientHttpRequestFactory> requestFactory) {
Assert.notNull(requestFactory, "RequestFactory Supplier must not be null");
return new RestTemplateBuilder(this.requestFactoryCustomizer, this.detectRequestFactory, this.rootUri, this.messageConverters, this.interceptors, requestFactory, this.uriTemplateHandler, this.errorHandler, this.basicAuthentication, this.defaultHeaders, this.customizers, this.requestCustomizers);
}
上面写法调用了requestFactory方法,返回的新Builder没有接收,用的还是旧的Builder,导致没有生效,正确写法应该是
restTemplate = builder.requestFactory(() -> httpComponentsClientHttpRequestFactory).build();
改了后,发现自己定义的RetryHandler生效了