SpringBoot之RestTemplate使用Apache的HttpClient连接池

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

pom.xml

复制代码
		<!-- RestTemplate使用Apache的HttpComponentsClientHttpRequestFactory替换掉Spring SimpleClientHttpRequestFactory 以使用Apache HttpClient的连接池。 -->
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>

RestTemplate配置类

java 复制代码
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;

@Configuration
public class RestTemplateConfig {

    @Bean
    public 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);
    }

}

调用

java 复制代码
	@Autowired  
	private 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

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

使用WebClient自定义连接池

java 复制代码
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;  
  
@Service  
public class CustomHttpClientService {  
  
    private final WebClient webClient;  
  
    @Autowired  
    public 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();  
    }  
}
相关推荐
ZGG00311 小时前
线程池详解:从 7 大参数到生产避坑
java·数据库·后端
geovindu12 小时前
CSharp: Wordcloud
开发语言·后端·c#·.net·.netcore·词云
苏生Susheng12 小时前
【软件实施】Windows 服务器运维实战
java·运维·服务器·windows·spring boot·javaweb·实施
geovindu13 小时前
CSharp: Command Pattern
开发语言·后端·c#·.net·.netcore·命令模式·行为模式
tedcloud12314 小时前
OpenLogi 怎么搭建?用 Rust 打造一个轻量的 Logitech 外设管理工具
linux·运维·服务器·开发语言·后端·rust·开源
学长毕业设计15 小时前
基于SpringBoot的健康食谱管理系统的设计与实现(源码+文档+讲解视频)
java·spring boot·后端
逃逸线LOF15 小时前
Spring的AOP简介
java·后端·spring
数智启示录15 小时前
Apache Kafka Consumer 扩到 40 个仍不提速:Partition 上限锁死有效并行度 【Kafka合集】
数据库·经验分享·分布式·缓存·面试·kafka·apache
数智启示录15 小时前
Apache Kafka 幂等 Producer 的边界:Exactly-Once 到了 MySQL 为什么失效 【Kafka合集】
数据库·经验分享·分布式·mysql·面试·kafka·apache
yume_sibai16 小时前
02-Rust 所有权与借用深入解析(底层原理 + 借用检查器 + 生命周期 + 内部可变性)
开发语言·后端·rust