OKHttp系列十一、ConnectInterceptor连接池拦截器

包含两个方面的内容,一是网络连接角度发挥作用的网络拦截器,二是从连接池的操作角度发挥作用的拦截器。
1、网络连接拦截器,ConnectInterceptor.java的代码很少,逻辑比较简单:

public final class ConnectInterceptor implements Interceptor {
	public final OkHttpClient client;
	public ConnectInterceptor(OkHttpClient client) {
		this.client = client;
	}
	@Override public Response intercept(Chain chain) throws IOException {
		RealInterceptorChain realChain = (RealInterceptorChain) chain;
		Request request = realChain.request();
		StreamAllocation streamAllocation = realChain.streamAllocation();
		boolean doExtensiveHealthChecks = !request.method().equals("GET");
		HttpCodec httpCodec = streamAllocation.newStream(client, chain, doExtensiveHealthChecks);
		RealConnection connection = streamAllocation.connection();
		return realChain.proceed(request, streamAllocation, httpCodec, connection);
	}
}

分析入口依然是我们最熟悉的地方:intercept();该方法的前三行分别创建了三个对象。这里我们重点关注StreamAllocation.
StreamAllocation的作用:用来建立执行OKHttp请求所需要的网络参数组件,分配Stream。
前面在RetryAndFollowUpInterceptor重定向拦截器里面我们家提到过,StreamAllocation在哪里被创建出来,但是真正的使用是在ConnectInterceptor里面,这不,现在我们就在分析这块了。
StreamAllocation对象创建完成后,我们通过下面这段代码进行使用:

boolean doExtensiveHealthChecks = !request.method().equals("GET");
HttpCodec httpCodec = streamAllocation.newStream(client, chain, doExtensiveHealthChecks);

这里httpCodec对象是用来编码我们的Request和解码我们的response对象的。

RealConnection connection = streamAllocation.connection();

上面这行代码中RealConnection对象的作用——用来进行实际上的网络IO传输。
最后再通过realChain.proceed()来进行来节气的调用。

总结:

1、ConnectInterceptor获取从RetryAndFollowUpInterceptor重定向拦截器传过来的StreamAllocation对象,然后创建HttpCodec对象和RealConnection对象。
	HttpCodec对象主要用于编码我们的Request和解码我们的response对象;RealConnection对象用来进行实际上的网络IO传输。
2、调用realChain.proceed()方法将我们刚刚创建的用于编码我们的Request和解码我们的response对象的HttpCodec对象和
	用来进行实际上的网络IO传输的RealConnection对象传递给下一个拦截器CallServerInterceptor。

在前面的源码中,有一个很重要的方法:streamAllocation.newStream()。现在我们再来看看这个方法的具体实现:

public HttpCodec newStream(OkHttpClient client, Interceptor.Chain chain, boolean doExtensiveHealthChecks) {
	int connectTimeout = chain.connectTimeoutMillis();
	int readTimeout = chain.readTimeoutMillis();
	int writeTimeout = chain.writeTimeoutMillis();
	int pingIntervalMillis = client.pingIntervalMillis();
	boolean connectionRetryEnabled = client.retryOnConnectionFailure();
	try {
		RealConnection resultConnection = findHealthyConnection(connectTimeout, readTimeout,writeTimeout, pingIntervalMillis, connectionRetryEnabled, doExtensiveHealthChecks);
		HttpCodec resultCodec = resultConnection.newCodec(client, chain, this);
		synchronized (connectionPool) {
			codec = resultCodec;
			return resultCodec;
		}
	} catch (IOException e) {
		throw new RouteException(e);
	}
}

这个方法代码量很小,前面5行代码都是通过chain获取参数,然后try{}代码块中,创建了RealConnection对象用来进行实际上的网络IO传输;HttpCodec对象用于编码我们的Request和解码我们的response对象。

RealConnection resultConnection = findHealthyConnection(connectTimeout, readTimeout,writeTimeout, pingIntervalMillis, connectionRetryEnabled, doExtensiveHealthChecks);
HttpCodec resultCodec = resultConnection.newCodec(client, chain, this);

总结起来就是:创建RealConnection对象和HttpCodec对象,然后选择连接方式,然后再将对象传递给传递给下一个拦截器CallServerInterceptor。

StreamAllocation.java里面有一个连接池的类:ConnectionPool.java,从名字就可以知道他的作用——连接池。他是StreamAllocation.java的核心,链接的管理和回收就由他来实现。有兴趣的可以深入研究。

原创文章 118 获赞 149 访问量 9万+

猜你喜欢

转载自blog.csdn.net/haoyuegongzi/article/details/103517222