探索HttpClient中的close方法及其對連接的影響
序
本文主要研究一下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聲明實(shí)現(xiàn)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,其構(gòu)造器要求傳入closeables,它實(shí)現(xiàn)了close方法,它主要是遍歷closeables,挨個執(zhí)行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參數(shù)為false的時候(默認(rèn))會創(chuàng)建closeablesCopy,創(chuàng)建Closeable去關(guān)閉HttpClientConnectionManager并添加到closeablesCopy中;
在開啟evictExpiredConnections或者evictIdleConnections的時候會創(chuàng)建IdleConnectionEvictor,然后創(chuàng)建關(guān)閉connectionEvictor的Closeable添加到closeablesCopy中
最后將這些closeablesCopy傳遞給InternalHttpClient的構(gòu)造器
小結(jié)
HttpClient(CloseableHttpClient
)的close方法會關(guān)閉一系列的Closeable,這些Closeable在HttpClientBuilder的build方法會構(gòu)建好然后傳遞給InternalHttpClient;默認(rèn)情況下這些closeable包括HttpClientConnectionManager的關(guān)閉、IdleConnectionEvictor的關(guān)閉。
以上就是探索HttpClient中的close方法及其對連接的影響的詳細(xì)內(nèi)容,更多關(guān)于HttpClient close方法的資料請關(guān)注腳本之家其它相關(guān)文章!
- httpclient connect連接請求方法源碼解讀
- httpclient getPoolEntryBlocking連接池方法源碼解讀
- httpclient staleConnectionCheckEnabled獲取連接流程解析
- 解讀httpclient的validateAfterInactivity連接池狀態(tài)檢測
- httpclient的disableConnectionState方法工作流程
- HttpClient的RedirectStrategy重定向處理核心機(jī)制
- HttpClient HttpRoutePlanner接口確定請求目標(biāo)路由
- httpclient ConnectionHolder連接池連接保持源碼解析
相關(guān)文章
Java前后端的JSON傳輸方式(前后端JSON格式轉(zhuǎn)換)
這篇文章主要介紹了Java前后端的JSON傳輸方式(前后端JSON格式轉(zhuǎn)換),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04SpringBoot整合WebSocket實(shí)現(xiàn)實(shí)時通信功能
在當(dāng)今互聯(lián)網(wǎng)時代,實(shí)時通信已經(jīng)成為了許多應(yīng)用程序的基本需求,而WebSocket作為一種全雙工通信協(xié)議,為開發(fā)者提供了一種簡單、高效的實(shí)時通信解決方案,本文將介紹如何使用SpringBoot框架來實(shí)現(xiàn)WebSocket的集成,快速搭建實(shí)時通信功能,感興趣的朋友可以參考下2023-11-11JAVA Iterator接口與增強(qiáng)for循環(huán)的實(shí)現(xiàn)
這篇文章主要介紹了JAVA Iterator接口與增強(qiáng)for循環(huán)的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11SpringBoot Actuator未授權(quán)訪問漏洞解決方案
工作的時候遇到過提示Spring Boot后端存在Actuator未授權(quán)訪問漏洞,網(wǎng)上有很多詳細(xì)的解釋文章,在這里做一個簡單的總結(jié)、介紹和分享,需要的朋友可以參考下2023-09-09Java concurrency集合之 CopyOnWriteArrayList_動力節(jié)點(diǎn)Java學(xué)院整理
這篇文章主要介紹了Java concurrency集合之 CopyOnWriteArrayList的相關(guān)資料,需要的朋友可以參考下2017-06-06SpringBoot注冊FilterRegistrationBean相關(guān)情況講解
這篇文章主要介紹了SpringBoot注冊FilterRegistrationBean相關(guān)情況,借助FilterRegistrationBean來注冊filter,可以避免在web.xml種配置filter這種原始的寫法2023-02-02