多个对象都有机会处理请求,将这些对象连成一个链,将请求沿着这条链传递,直到有对象处理为止。
/** * @Description 抽象处理者 */ public abstract class Handler { //下一个处理者 private Handler mNextHandler; public Handler(){ } /** * 传入下一个处理者 * @param nextHandler */ public Handler(Handler nextHandler) { this.mNextHandler = nextHandler; } /** * 处理请求 */ public final void handleRequest(Request request) { //请求者和处理者级别相同才进行处理 if (getCurLevel() == request.getRequestLevel()) { handle(request); } else { //否则将请求交给下一个处理者 if (mNextHandler != null) { mNextHandler.handleRequest(request); } else { System.out.print("无人处理"); } } } /** * 获取处理者的级别 * @return */ protected abstract int getCurLevel(); /** * 当前处理者处理的逻辑 * @param request */ protected abstract void handle(Request request); } 复制代码
public class HandlerA extends Handler { public HandlerA(Handler nextHandler) { super(nextHandler); } @Override protected int getCurLevel() { return 6; } @Override protected void handle(Request request) { System.out.print("HandlerA 进行处理"); } } 复制代码
public class HandlerB extends Handler { public HandlerB() { } public HandlerB(Handler nextHandler) { super(nextHandler); } @Override protected int getCurLevel() { return 10; } @Override protected void handle(Request request) { System.out.print("HandlerB 进行处理"); } } 复制代码
public abstract class Request { /** * @return 请求的级别 */ public abstract int getRequestLevel(); } 复制代码
public class RequestA extends Request { @Override public int getRequestLevel() { return 10; } } 复制代码
public class HandlerTest { public static void main(String[] args) { RequestA request = new RequestA(); //最后一个处理者 Handler handlerB = new HandlerB(); //第一个处理者 Handler handlerA = new HandlerA(handlerB); //最终传递到HandlerB处理 handlerA.handleRequest(request); } } 复制代码
纯的责任链模式是如果被处理者进行处理了,则请求传递结束。OkHttp的拦截器是不纯的责任链模式,在请求到达时,拦截器会做一些处理(比如添加参数等),然后传递给下一个拦截器进行处理。
在请求过程中,通过拦截器对请求进行处理
Response response = getResponseWithInterceptorChain(); 复制代码
Response getResponseWithInterceptorChain() throws IOException { // 创建拦截器的list List<Interceptor> interceptors = new ArrayList<>(); interceptors.addAll(client.interceptors()); interceptors.add(retryAndFollowUpInterceptor); interceptors.add(new BridgeInterceptor(client.cookieJar())); interceptors.add(new CacheInterceptor(client.internalCache())); interceptors.add(new ConnectInterceptor(client)); if (!forWebSocket) { interceptors.addAll(client.networkInterceptors()); } interceptors.add(new CallServerInterceptor(forWebSocket)); // 创建RealInterceptorChain,传入的index索引为0 Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0, originalRequest, this, eventListener, client.connectTimeoutMillis(), client.readTimeoutMillis(), client.writeTimeoutMillis()); return chain.proceed(originalRequest); } 复制代码
创建首个RealInterceptorChain对象,并传入拦截器的集合,通过proceed进行请求的处理。
public Response proceed(Request request, StreamAllocation streamAllocation, HttpCodec httpCodec, RealConnection connection) throws IOException { ...... // 创建下一个RealInterceptorChain,将index+1(下一个拦截器索引)传入 RealInterceptorChain next = new RealInterceptorChain(interceptors, streamAllocation, httpCodec, connection, index + 1, request, call, eventListener, connectTimeout, readTimeout, writeTimeout); //获取当前的拦截器 Interceptor interceptor = interceptors.get(index); //通过Interceptor的intercept进行处理 Response response = interceptor.intercept(next); ...... return response; } 复制代码
public interface Interceptor { /** * 拦截Chain,并触发下一个拦截器的调用 * @param chain 被处理的对象 * @return * @throws IOException */ Response intercept(Chain chain) throws IOException; interface Chain { //返回请求 Request request(); //对请求进行处理 Response proceed(Request request) throws IOException; ...... } } 复制代码
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 request = realChain.request(); StreamAllocation streamAllocation = realChain.streamAllocation(); // We need the network to satisfy this request. Possibly for validating a conditional GET. boolean doExtensiveHealthChecks = !request.method().equals("GET"); HttpCodec httpCodec = streamAllocation.newStream(client, chain, doExtensiveHealthChecks); RealConnection connection = streamAllocation.connection(); //会调用下一个拦截链的proceed进行处理 return realChain.proceed(request, streamAllocation, httpCodec, connection); } } 复制代码
ConnectInterceptor作为一个具体的处理者,接收到下一个RealInterceptorChain对象,通过RealInterceptorChain的proceed方法对请求进行处理。
整个链式调用的流程为:
首个Chain procced--首个Interceptor interceptor--
下一个Chain procced--下一个Interceptor interceptor--
下一个Chain procced--下一个Interceptor interceptor....