Forked from jkuipers/HttpClientAutoConfiguration.java
Created
February 29, 2020 09:13
-
-
Save dimitrisli/c0f0128a936e25c8c6383798737f2222 to your computer and use it in GitHub Desktop.
Spring Boot auto-configuration example for an Apache Components HTTP client and its usage in all RestTemplates created by the RestTemplateBuilder, plus trace logging support
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import org.apache.http.client.HttpClient; | |
import org.apache.http.client.config.CookieSpecs; | |
import org.apache.http.client.config.RequestConfig; | |
import org.apache.http.impl.client.CloseableHttpClient; | |
import org.apache.http.impl.client.HttpClients; | |
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; | |
import org.springframework.boot.context.properties.EnableConfigurationProperties; | |
import org.springframework.boot.web.client.RestTemplateCustomizer; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.http.client.BufferingClientHttpRequestFactory; | |
import org.springframework.http.client.ClientHttpRequestFactory; | |
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; | |
import org.springframework.http.client.InterceptingClientHttpRequestFactory; | |
import org.springframework.util.ReflectionUtils; | |
import org.springframework.web.client.RestTemplate; | |
import java.lang.reflect.Field; | |
/** | |
* Ensures that every {@link org.springframework.web.client.RestTemplate} built with a | |
* {@link org.springframework.boot.web.client.RestTemplateBuilder} uses an Apache Components | |
* HTTP client using a pooling connection pool with the configured number of maximum connections | |
* (default is way too small) and time-out settings. | |
*/ | |
@Configuration | |
@EnableConfigurationProperties(HttpClientProperties.class) | |
public class HttpClientAutoConfiguration { | |
@Autowired HttpClientProperties client; | |
@Bean | |
@ConditionalOnMissingBean | |
CloseableHttpClient httpClient() { | |
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); | |
// since most services only connect to a single backend | |
// we use the same value for max per-route and total | |
connectionManager.setDefaultMaxPerRoute(client.getMaxConnections()); | |
connectionManager.setMaxTotal(client.getMaxConnections()); | |
RequestConfig requestConfig = RequestConfig.custom() | |
.setConnectTimeout(client.getConnectionTimeoutInMillis()) | |
.setSocketTimeout(client.getReadTimeoutInMillis()) | |
.setCookieSpec(CookieSpecs.STANDARD) | |
.build(); | |
return HttpClients.custom() | |
.setConnectionManager(connectionManager) | |
.setDefaultRequestConfig(requestConfig) | |
.build(); | |
} | |
@Bean | |
RestTemplateCustomizer httpClientCustomizer(HttpClient httpClient) { | |
return restTemplate -> { | |
ClientHttpRequestFactory requestFactory = restTemplate.getRequestFactory(); | |
// not-so-proudly copied from the TestRestTemplate code: | |
if (requestFactory instanceof InterceptingClientHttpRequestFactory) { | |
Field requestFactoryField = ReflectionUtils.findField(RestTemplate.class, "requestFactory"); | |
ReflectionUtils.makeAccessible(requestFactoryField); | |
requestFactory = (ClientHttpRequestFactory) ReflectionUtils.getField(requestFactoryField, restTemplate); | |
} | |
if (requestFactory instanceof HttpComponentsClientHttpRequestFactory) { | |
HttpComponentsClientHttpRequestFactory clientRequestFactory = | |
(HttpComponentsClientHttpRequestFactory) requestFactory; | |
clientRequestFactory.setHttpClient(httpClient); | |
if (client.isLoggingEnabled()) { | |
restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(requestFactory)); | |
restTemplate.getInterceptors().add(new LoggingClientHttpRequestInterceptor()); | |
} | |
} | |
}; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment