前面已经分析,okHttp的线程池里的请求任务的execute方法会构造拦截器链,然后通过index++依次调用chain.proceed方法来调用各种拦截器,不考虑用户自定义的拦截器的话,第一个被调用的拦截器就是RetryAndFollowUpInterceptor,请求重试拦截器,我们主要看被调用的方法intercept
public Response intercept(Chain chain) throws IOException { Request request = chain.request(); RealInterceptorChain realChain = (RealInterceptorChain) chain; Call call = realChain.call(); EventListener eventListener = realChain.eventListener();//StreamAllocation用于协调 连接Connections、数据流Streams 和 网络请求Calls这三个实体 StreamAllocation streamAllocation = new StreamAllocation(client.connectionPool(), createAddress(request.url()), call, eventListener, callStackTrace); this.streamAllocation = streamAllocation;//重定向次数 int followUpCount = 0; Response priorResponse = null; while (true) { if (canceled) { streamAllocation.release(); throw new IOException("Canceled"); } Response response; boolean releaseConnection = true; try { //调用下层的拦截器做网络请求 response = realChain.proceed(request, streamAllocation, null, null); releaseConnection = false; } catch (RouteException e) { //捕获RouteException,并判断本次请求的异常是否能通过重新请求来恢复(比方ProtocolException协议出错,则返回false不能重连) if (!recover(e.getLastConnectException(), streamAllocation, false, request)) { //不能则抛异常 throw e.getFirstConnectException(); } releaseConnection = false; //可以则continue,while循环体内重新请求一遍 continue; } catch (IOException e) { //逻辑和上面的一样,捕获更大范围的异常 boolean requestSendStarted = !(e instanceof ConnectionShutdownException); if (!recover(e, streamAllocation, requestSendStarted, request)) throw e; releaseConnection = false; continue; } finally { //释放当前的连接资源 if (releaseConnection) { streamAllocation.streamFailed(null); streamAllocation.release(); } } // Attach the prior response if it exists、Such responses never have a body. if (priorResponse != null) { response = response.newBuilder() .priorResponse(priorResponse.newBuilder() .body(null) .build()) .build(); } Request followUp; try { //如果上面返回了response,那么判断httpCode,具体的code做具体处理(比方407,代理认证失败,则调用代理管理类进行认证) followUp = followUpRequest(response, streamAllocation.route()); } catch (IOException e) { streamAllocation.release(); throw e; } //没有进一步的处理方法,(包括请求成功的)则返回null,此时直接返回response给上层处理 if (followUp == null) { streamAllocation.release(); return response; } closeQuietly(response.body()); //重定向次数如果大于最大允许的重定向次数,则抛异常 if (++followUpCount > MAX_FOLLOW_UPS) { streamAllocation.release(); throw new ProtocolException("Too many follow-up requests: " + followUpCount); } if (followUp.body() instanceof UnrepeatableRequestBody) { streamAllocation.release(); throw new HttpRetryException("Cannot retry streamed HTTP body", response.code()); } if (!sameConnection(response, followUp.url())) { streamAllocation.release(); streamAllocation = new StreamAllocation(client.connectionPool(), createAddress(followUp.url()), call, eventListener, callStackTrace); this.streamAllocation = streamAllocation; } else if (streamAllocation.codec() != null) { throw new IllegalStateException("Closing the body of " + response + " didn't close its backing stream、Bad interceptor?"); } request = followUp; priorResponse = response; }}