Search results
Configure a single RestTemplate Bean to use Apache HttpClient 5 Connection Pool
application.yml
:
asimiotech:
resttemplate:
max-total: 20
default-max-per-route: 20
conn-timeout-millis: 4000
conn-request-timeout-millis: 4000
socket-timeout-millis: 4000
routes:
-
scheme: http
host: localhost
port: 8000
max-per-route: 20
RestTemplateProperties.java
:
@Configuration
@ConfigurationProperties(prefix = "asimiotech.resttemplate")
@Getter
@Setter
public class RestTemplateProperties {
private Integer maxTotal;
private Integer defaultMaxPerRoute;
private Integer connTimeoutMillis;
private Integer connRequestTimeoutMillis;
private Integer socketTimeoutMillis;
private List<RouteProperties> routes;
@Getter
@Setter
public static class RouteProperties {
private String scheme;
private String host;
private Integer port;
private Integer maxPerRoute;
}
}
RestTemplateConfig.java
:
@Configuration
@EnableConfigurationProperties(RestTemplateProperties.class)
@RequiredArgsConstructor
public class RestTemplateConfig {
private final RestTemplateProperties restTemplateProperties;
@Bean
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
PoolingHttpClientConnectionManager result = new PoolingHttpClientConnectionManager();
result.setMaxTotal(this.restTemplateProperties.getMaxTotal());
// Default max per route is used in case it's not set for a specific route
result.setDefaultMaxPerRoute(this.restTemplateProperties.getDefaultMaxPerRoute());
// Adding individual route configuration when they exist
this.restTemplateProperties.getRoutes().stream()
.forEach(route -> this.addNewRoute(result, route));
return result;
}
@Bean
public RequestConfig requestConfig() {
return RequestConfig.custom()
.setConnectionRequestTimeout(this.restTemplateProperties.getConnRequestTimeoutMillis(), TimeUnit.MILLISECONDS)
.setConnectTimeout(this.restTemplateProperties.getConnTimeoutMillis(), TimeUnit.MILLISECONDS)
.setResponseTimeout(this.restTemplateProperties.getSocketTimeoutMillis(), TimeUnit.MILLISECONDS)
.build();
}
@Bean
public CloseableHttpClient apacheHttpClient(
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager,
RequestConfig requestConfig) {
CloseableHttpClient result = HttpClientBuilder.create()
.setConnectionManager(poolingHttpClientConnectionManager)
.setDefaultRequestConfig(requestConfig)
.build();
return result;
}
@Bean
public RestTemplate restTemplate(HttpClient httpClient) {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
requestFactory.setHttpClient(httpClient);
return new RestTemplate(requestFactory);
}
private void addNewRoute(PoolingHttpClientConnectionManager connectionManager, RouteProperties route) {
HttpHost host = new HttpHost(route.getScheme(), route.getHost(), route.getPort());
// Max per route for a specific host route
connectionManager.setMaxPerRoute(new HttpRoute(host), route.getMaxPerRoute());
}
}
Usage
ClassThatSendsHttpRequests.java
:
@RequiredArgsConstructor
public class ClassThatSendsHttpRequests {
private final RestTemplate restTemplate;
// ...
}
Warning:
Read on if you are interested in learning how RestTemplate’s wrong configuration leads to RestTemplate Requests Timeout.