探索HttpClient中的close方法及其对连接的影响
作者:codecraft
序
本文主要研究一下HttpClient的close
CloseableHttpClient
org/apache/http/impl/client/CloseableHttpClient.java
@Contract(threading = ThreadingBehavior.SAFE) public abstract class CloseableHttpClient implements HttpClient, Closeable { @Override public <T> T execute(final HttpHost target, final HttpRequest request, final ResponseHandler<? extends T> responseHandler, final HttpContext context) throws IOException, ClientProtocolException { Args.notNull(responseHandler, "Response handler"); final CloseableHttpResponse response = execute(target, request, context); try { final T result = responseHandler.handleResponse(response); final HttpEntity entity = response.getEntity(); EntityUtils.consume(entity); return result; } catch (final ClientProtocolException t) { // Try to salvage the underlying connection in case of a protocol exception final HttpEntity entity = response.getEntity(); try { EntityUtils.consume(entity); } catch (final Exception t2) { // Log this exception. The original exception is more // important and will be thrown to the caller. this.log.warn("Error consuming content after an exception.", t2); } throw t; } finally { response.close(); } } //...... }
CloseableHttpClient声明实现HttpClient, Closeable接口
InternalHttpClient
org/apache/http/impl/client/InternalHttpClient.java
@Contract(threading = ThreadingBehavior.SAFE_CONDITIONAL) @SuppressWarnings("deprecation") class InternalHttpClient extends CloseableHttpClient implements Configurable { private final Log log = LogFactory.getLog(getClass()); private final ClientExecChain execChain; private final HttpClientConnectionManager connManager; private final HttpRoutePlanner routePlanner; private final Lookup<CookieSpecProvider> cookieSpecRegistry; private final Lookup<AuthSchemeProvider> authSchemeRegistry; private final CookieStore cookieStore; private final CredentialsProvider credentialsProvider; private final RequestConfig defaultConfig; private final List<Closeable> closeables; public InternalHttpClient( final ClientExecChain execChain, final HttpClientConnectionManager connManager, final HttpRoutePlanner routePlanner, final Lookup<CookieSpecProvider> cookieSpecRegistry, final Lookup<AuthSchemeProvider> authSchemeRegistry, final CookieStore cookieStore, final CredentialsProvider credentialsProvider, final RequestConfig defaultConfig, final List<Closeable> closeables) { super(); Args.notNull(execChain, "HTTP client exec chain"); Args.notNull(connManager, "HTTP connection manager"); Args.notNull(routePlanner, "HTTP route planner"); this.execChain = execChain; this.connManager = connManager; this.routePlanner = routePlanner; this.cookieSpecRegistry = cookieSpecRegistry; this.authSchemeRegistry = authSchemeRegistry; this.cookieStore = cookieStore; this.credentialsProvider = credentialsProvider; this.defaultConfig = defaultConfig; this.closeables = closeables; } //...... @Override public void close() { if (this.closeables != null) { for (final Closeable closeable: this.closeables) { try { closeable.close(); } catch (final IOException ex) { this.log.error(ex.getMessage(), ex); } } } } }
InternalHttpClient继承了CloseableHttpClient,其构造器要求传入closeables,它实现了close方法,它主要是遍历closeables,挨个执行close
HttpClientBuilder
org/apache/http/impl/client/HttpClientBuilder.java
public class HttpClientBuilder { private List<Closeable> closeables; private boolean connManagerShared; //...... /** * For internal use. */ protected void addCloseable(final Closeable closeable) { if (closeable == null) { return; } if (closeables == null) { closeables = new ArrayList<Closeable>(); } closeables.add(closeable); } public CloseableHttpClient build() { //...... List<Closeable> closeablesCopy = closeables != null ? new ArrayList<Closeable>(closeables) : null; if (!this.connManagerShared) { if (closeablesCopy == null) { closeablesCopy = new ArrayList<Closeable>(1); } final HttpClientConnectionManager cm = connManagerCopy; if (evictExpiredConnections || evictIdleConnections) { final IdleConnectionEvictor connectionEvictor = new IdleConnectionEvictor(cm, maxIdleTime > 0 ? maxIdleTime : 10, maxIdleTimeUnit != null ? maxIdleTimeUnit : TimeUnit.SECONDS, maxIdleTime, maxIdleTimeUnit); closeablesCopy.add(new Closeable() { @Override public void close() throws IOException { connectionEvictor.shutdown(); try { connectionEvictor.awaitTermination(1L, TimeUnit.SECONDS); } catch (final InterruptedException interrupted) { Thread.currentThread().interrupt(); } } }); connectionEvictor.start(); } closeablesCopy.add(new Closeable() { @Override public void close() throws IOException { cm.shutdown(); } }); } //...... return new InternalHttpClient( execChain, connManagerCopy, routePlannerCopy, cookieSpecRegistryCopy, authSchemeRegistryCopy, defaultCookieStore, defaultCredentialsProvider, defaultRequestConfig != null ? defaultRequestConfig : RequestConfig.DEFAULT, closeablesCopy); } }
HttpClientBuilder定义了addCloseable方法用于添加closeable,不过是protected;而build方法在connManagerShared参数为false的时候(默认)会创建closeablesCopy,创建Closeable去关闭HttpClientConnectionManager并添加到closeablesCopy中;
在开启evictExpiredConnections或者evictIdleConnections的时候会创建IdleConnectionEvictor,然后创建关闭connectionEvictor的Closeable添加到closeablesCopy中
最后将这些closeablesCopy传递给InternalHttpClient的构造器
小结
HttpClient(CloseableHttpClient
)的close方法会关闭一系列的Closeable,这些Closeable在HttpClientBuilder的build方法会构建好然后传递给InternalHttpClient;默认情况下这些closeable包括HttpClientConnectionManager的关闭、IdleConnectionEvictor的关闭。
以上就是探索HttpClient中的close方法及其对连接的影响的详细内容,更多关于HttpClient close方法的资料请关注脚本之家其它相关文章!
您可能感兴趣的文章:
- httpclient connect连接请求方法源码解读
- httpclient getPoolEntryBlocking连接池方法源码解读
- httpclient staleConnectionCheckEnabled获取连接流程解析
- 解读httpclient的validateAfterInactivity连接池状态检测
- httpclient的disableConnectionState方法工作流程
- HttpClient的RedirectStrategy重定向处理核心机制
- HttpClient HttpRoutePlanner接口确定请求目标路由
- httpclient ConnectionHolder连接池连接保持源码解析