SpringBoot自带的RestTemplate是没有使用连接池的,只是SimpleClientHttpRequestFactory实现了ClientHttpRequestFactory、AsyncClientHttpRequestFactory 2个工厂接口,因此每次调用接口都会创建连接和销毁连接,如果是高并发场景下会大大降低性能。因此,我们可以使用Apache的HttpClient连接池。

pom.xml

org.apache.httpcomponentshttpclient

RestTemplate配置类

import org.apache.http.client.HttpClient;import org.apache.http.client.config.RequestConfig;import org.apache.http.impl.client.HttpClientBuilder;import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.http.client.ClientHttpRequestFactory;import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;import org.springframework.web.client.RestTemplate;@Configurationpublic class RestTemplateConfig {@Beanpublic RestTemplate restTemplate() {PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();connectionManager.setMaxTotal(50);connectionManager.setDefaultMaxPerRoute(20);RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(5000) // timeout to get connection from pool.setSocketTimeout(5000) // standard connection timeout.setConnectTimeout(5000) // standard connection timeout.build();HttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager).setDefaultRequestConfig(requestConfig).build();ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);return new RestTemplate(requestFactory);}}

调用

@Autowiredprivate RestTemplate restTemplate;public Res getData(Dto dto) {String url = "https://xxx.com/api/xxx";//封装请求头参数.HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);headers.set("Content-Type", "application/json;charset=utf-8");headers.set("自定义请求头key","自定义请求头value");Res res = restTemplate.postForEntity(url, new HttpEntity<>(dto, headers), Res.class).getBody();return res;}

注意

在Spring Boot中,RestTemplate已经过时,建议使用更现代的RestTemplateBuilder和WebClient。

使用RestTemplateBuilder

import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.reactive.function.client.WebClient;@Servicepublic class HttpClientService {private final RestTemplateBuilder restTemplateBuilder;@Autowiredpublic HttpClientService(RestTemplateBuilder restTemplateBuilder) {this.restTemplateBuilder = restTemplateBuilder;}public String getData(String url) {return restTemplateBuilder.build().getForObject(url, String.class);}}

使用WebClient自定义连接池

import org.springframework.beans.factory.annotation.Value;import org.springframework.http.HttpMethod;import org.springframework.stereotype.Service;import org.springframework.web.reactive.function.client.WebClient;@Servicepublic class CustomHttpClientService {private final WebClient webClient;@Autowiredpublic CustomHttpClientService(@Value("${custom.pool.size:10}") int poolSize) {this.webClient = WebClient.builder().poolSize(poolSize) // 设置连接池大小等其它参数,这里不在一一赘述。.build();}public String getData(String url) {return webClient.method(HttpMethod.GET).uri(url).retrieve().bodyToMono(String.class).block();}}