CloseableHttpResponse用完需要手动关闭吗

发布时间:2021-10-26 07:38:08

不用。

前提是调用了EntityUtils去读取过了。


当我们使用调用CloseableHttpClient的时候,调用CloseableHttpClient.execute(httpPost)方法会返回CloseableHttpResponse对象,CloseableHttpResponse的唯一实现类是HttpResponseProxy,我们来研究下不手动close,这个对象能否被正常回收,是否有资源被占用等bad situations


分析下HttpResponseProxy源码,发现这个类只有两个成员变量,分别是HttpResponse和ConnectionHolder:只要这俩被回收,就是jvm安全的。



HttpResponse在这里是BasicHttpResponse,这个对象里有一个HttpEntity的成员变量,HttpEntity里有一个输入流



只要这个流被回收了就是安全的。


然后再来看看ConnectionHolder里有什么



额,manager和managedConn这是什么?先不管,看下方法栈



只要manager和managedConn被回收了就是安全的。


?


好,我们回去看HttpResponseProxy,注意看HttpResponseProxy的构造函数,response这个对象被增强了,response.getEntity得到的对象将变ResponseEntityProxy,注意这个类实现了EofSensorWatcher


// 构造函数
public HttpResponseProxy(final HttpResponse original, final ConnectionHolder connHolder) {
this.original = original;
this.connHolder = connHolder;
ResponseEntityProxy.enchance(original, connHolder);
}


// 增强代码
class ResponseEntityProxy extends HttpEntityWrapper implements EofSensorWatcher {

private final ConnectionHolder connHolder;

public static void enchance(final HttpResponse response, final ConnectionHolder connHolder) {
final HttpEntity entity = response.getEntity();
if (entity != null && entity.isStreaming() && connHolder != null) {
response.setEntity(new ResponseEntityProxy(entity, connHolder));
}
}

当我们调用EntityUtils.toString方法去消费entity对象,这个方法会调用entity的getContent方法去获取输入流。



而这个entity就是增强后的这个ResponseEntityProxy,这个对象的getContent方法返回了EofSensorInputStream。(第二个参数this表示把这个inputStream的EofSensorWatcher设置为ResponseEntityProxy对象)


@Override
public InputStream getContent() throws IOException {
return new EofSensorInputStream(this.wrappedEntity.getContent(), this);
}

?


EofSensorInputStream.java


@Override
public int read(final byte[] b, final int off, final int len) throws IOException {
int l = -1;

if (isReadAllowed()) {
try {
l = wrappedStream.read(b, off, len);
checkEOF(l);
} catch (final IOException ex) {
checkAbort();
throw ex;
}
}

return l;
}


protected void checkEOF(final int eof) throws IOException {

final InputStream toCheckStream = wrappedStream;
if ((toCheckStream != null) && (eof < 0)) {
try {
boolean scws = true; // should close wrapped stream?
if (eofWatcher != null) {
scws = eofWatcher.eofDetected(toCheckStream);
}
if (scws) {
toCheckStream.close();
}
} finally {
wrappedStream = null;
}
}
}

?


ResponseEntityProxy实现EofSensorWatcher接口,这个就是HttpResponse里的entity对象,releaseConnection用于清除这个代理对象的connHolder对象,也就是HttpResponseProxy的ConnectionHolder对象。



@Override
public boolean eofDetected(final InputStream wrapped) throws IOException {
try {
// there may be some cleanup required, such as
// reading trailers after the response body:
if (wrapped != null) {
wrapped.close();
}
releaseConnection();
} catch (final IOException ex) {
abortConnection();
throw ex;
} catch (final RuntimeException ex) {
abortConnection();
throw ex;
} finally {
cleanup();
}
return false;
}

?


httpcomponent4.5以*姹荆鲜褂 EofSensorInputStream 作为输入流,这个流对象在每次读取之后都会检查是否已经读取到末尾,如果读取完,则关闭ChunkedInputStream并释放连接 releaseConnection(),就算没有关闭,如果是通过apache的EntityUtils的toString方法获取HttpEntity对象里的内容,也会在return之前执行finally里的close方法


releaseConnection这个方法释放了最开始我们提到的ConnectionHolder,而close方法则关闭了HttpResponse里的流,因此最后是安全的,即使没有手动调用close方法,全部得益于EofSensorInputStream这个输入流。


老眼昏花,写的比较乱。太难了。。。。。

相关文档

  • 销售心态培训心得
  • 2020年江苏省苏州大学招聘专职研究生辅导员启事
  • 文言文观潮翻译及注释
  • 高中英语写作表结果的句型和连接词汇总
  • 蛋碎是什么意思 蛋碎了
  • 在腾讯云&阿里云上部署JavaWeb项目(Tomcat+MySQL)
  • 判断葡萄酒是否变质的方法
  • 芦荟有什么作用与功效
  • 台湾留学生活费一个月多少钱
  • NIO与普通IO文件读写性能对比
  • 你是水中盛开的白莲诗歌
  • 简洁的国防的手抄报内容
  • 逆境重生鼓舞人心的话
  • 华东政法大学校长建议宪法日全国放假
  • 2016~2017二年级上册数学期末考试卷
  • 小学体育运动主题黑板报
  • 创作排行有感
  • 如何浇花常识
  • fresh馥蕾诗修女面霜怎么样馥蕾诗修女面霜好用吗
  • 钢琴练习的注意事项
  • 微信里的微信运动是什么意思里面的步数又是什么
  • 图书捐赠合同书范本
  • 学霸的个人学习计划精选
  • Hexo+Netlify快速搭建个人博客
  • 圆明园晚上几点关门
  • 雪趣作文700字
  • 失恋伤心长的个性签名
  • Nginx Windows版的服务安装和管理工具
  • 数字拼图排行榜前十名
  • 自学python需要买书吗-Python真的适合每个人学习吗 学习Python需要多久
  • 猜你喜欢

    电脑版