这是我的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;
}
使用PoolingHttpClientConnectionManager来管理连接。
可通过以下代码访问
ResponseEntity<String> response = restClient.exchange( url, HttpMethod.GET, entity , String.class );
我需要在上述调用之后释放连接,还是由RestTemplate处理。如果我们需要照顾释放连接。
请有人解释/说明如何释放连接。
答案 0 :(得分:10)
您应该将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);
}
然后你可以使用这个bean来创建你的RestTemplate:
@Bean
@Qualifier("myRestService")
public RestTemplate createRestTemplate(ClientHttpRequestFactory factory) {
RestTemplate restTemplate = new RestTemplate(factory);
restTemplate.setErrorHandler(new RestResponseErrorHandler());
restTemplate.setMessageConverters(createMessageConverters());
return restTemplate;
}
答案 1 :(得分:7)
您提出的问题: 我需要在上述调用之后释放连接,还是由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();
}
}
}
响应提取器通过使用响应来为您工作 的 responseExtractor.extractData(响应); 强>
完全提取数据后,它也会关闭 response.close()。
答案 2 :(得分:0)
我认为答案在这里:org.springframework.remoting.httpinvoker.HttpComponentsHttpInvokerRequestExecutor#doExecuteRequest
@Override
protected RemoteInvocationResult doExecuteRequest(
HttpInvokerClientConfiguration config, ByteArrayOutputStream baos)
throws IOException, ClassNotFoundException {
HttpPost postMethod = createHttpPost(config);
setRequestBody(config, postMethod, baos);
try {
HttpResponse response = executeHttpPost(config, getHttpClient(), postMethod);
validateResponse(config, response);
InputStream responseBody = getResponseBody(config, response);
return readRemoteInvocationResult(responseBody, config.getCodebaseUrl());
}
finally {
postMethod.releaseConnection();
}
}