Spring RestTemplate - 需要释放连接吗?

Uma*_*mar 7 spring httpclient resttemplate

这是我的Rest模板配置,

    @Bean
    @Qualifier("myRestService")
    public RestTemplate createRestTemplate(@Value("${connection.timeout}") String maxConn) {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
         connectionManager.setMaxTotal(maxTotalConn);
         connectionManager.setDefaultMaxPerRoute(maxPerChannel);

        RequestConfig config = RequestConfig.custom().setConnectTimeout(100000).build();
        CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager)
                .setDefaultRequestConfig(config).build();
        ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient);

        RestTemplate restTemplate = new RestTemplate(factory);

        restTemplate.setErrorHandler(new RestResponseErrorHandler());
         restTemplate.setMessageConverters(createMessageConverters());

        return restTemplate;
    }
Run Code Online (Sandbox Code Playgroud)

我使用PoolingHttpClientConnectionManager来管理连接.

它可以通过以下代码访问,

ResponseEntity<String> response = restClient.exchange( url, HttpMethod.GET, entity , String.class );
Run Code Online (Sandbox Code Playgroud)

我是否需要在上述调用之后释放连接,或者是否由RestTemplate处理.如果我们需要照顾释放连接.

请有人解释/说明如何释放连接.

Wil*_*ven 13

您应该将ClientHttpRequestFactory声明为bean.通过将它声明为bean,它将由Spring bean工厂管理,它将在应用程序关闭时调用工厂的destroy方法,或者bean超出范围.ClientHttpRequestFactory的destroy方法将关闭底层ClientConnectionManager的连接池.您可以检查Spring API文档.

@Bean
public ClientHttpRequestFactory createRequestFactory(@Value("${connection.timeout}") String maxConn) {
    PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
     connectionManager.setMaxTotal(maxTotalConn);
     connectionManager.setDefaultMaxPerRoute(maxPerChannel);

    RequestConfig config = RequestConfig.custom().setConnectTimeout(100000).build();
    CloseableHttpClient httpClient = HttpClientBuilder.create().setConnectionManager(connectionManager)
            .setDefaultRequestConfig(config).build();
    return new HttpComponentsClientHttpRequestFactory(httpClient);
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用这个bean来创建你的RestTemplate:

@Bean
@Qualifier("myRestService")
public RestTemplate createRestTemplate(ClientHttpRequestFactory factory) {
    RestTemplate restTemplate = new RestTemplate(factory);

    restTemplate.setErrorHandler(new RestResponseErrorHandler());
    restTemplate.setMessageConverters(createMessageConverters());

    return restTemplate;
}
Run Code Online (Sandbox Code Playgroud)

  • 请您可以用代码示例更清楚地解释一下。 (2认同)

小智 9

您提出的问题: 我是否需要在上述调用之后释放连接,或者是否由RestTemplate处理.如果我们需要照顾释放连接.

不,如果使用resttemplate,则无需关闭响应上的连接.

从apache httpclient,您需要使用完整的响应(EntityUtils.consume(HttpEntity)并关闭响应).

这可以在ClientConnectionRelease.java中验证

但RestTemplate会为您执行此操作,以验证相同的内容,了解 RestTemplate.java

寻找方法

protected <T> T doExecute(URI url,...) {
 try {
        ClientHttpRequest request = this.createRequest(url, method);
        ...
        response = request.execute();
        ...
        if(responseExtractor != null) {
            var7 = responseExtractor.extractData(response);
            return var7;
        }
       ...
       ...
    } finally {
        if(response != null) {
            response.close();
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

响应提取器通过使用responseExtractor.extractData(response)消耗响应来为您工作 ;

在完全提取数据之后,它也关闭了response.close().