Spring RestTemplate - 需要释放连接?
Spring RestTemplate - Need to release connection?
这是我的 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 处理。如果我们需要注意释放连接。
请问有人explain/show如何释放连接。
您应该将 ClientHttpRequestFactory 声明为 bean。通过将其声明为 bean,它由 Spring bean 工厂管理,当应用程序关闭或 bean 超出范围时,它将调用工厂的 destroy 方法。 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;
}
您提出的问题:
我需要在上述调用后释放连接还是由 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()。
我想答案就在这里: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();
}
}
这是我的 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 处理。如果我们需要注意释放连接。
请问有人explain/show如何释放连接。
您应该将 ClientHttpRequestFactory 声明为 bean。通过将其声明为 bean,它由 Spring bean 工厂管理,当应用程序关闭或 bean 超出范围时,它将调用工厂的 destroy 方法。 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;
}
您提出的问题: 我需要在上述调用后释放连接还是由 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()。
我想答案就在这里: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();
}
}