今天我們來自己實(shí)現(xiàn)一個類似于okhttp里的interceptor功能
定義實(shí)體和攔截器接口:
請求實(shí)體:
public class LRequest {
}
返回實(shí)體:
public class LResponse {
}
攔截器:
public interface LInterceptor {
LResponse intercept(LChain lRequest) throws IOException;
interface LChain {
LRequest request();
LResponse proceed(LRequest request) throws IOException;
}
}
然后定義遞歸調(diào)用的實(shí)現(xiàn)類:
public class LRealInterceptorChain implements LInterceptor.LChain {
private List<LInterceptor> mLInterceptors;
private LRequest mLRequest;
private int mIndex;
public LRealInterceptorChain(List<LInterceptor> LInterceptors, LRequest LRequest, int index) {
mLInterceptors = LInterceptors;
mLRequest = LRequest;
mIndex = index;
}
@Override
public LRequest request() {
return mLRequest;
}
@Override
public LResponse proceed(LRequest request) throws IOException {
LRealInterceptorChain realInterceptorChain = new LRealInterceptorChain(mLInterceptors, request, mIndex + 1);
LInterceptor interceptor = mLInterceptors.get(mIndex);
//這里觸發(fā)了下一個攔截,產(chǎn)生了鏈?zhǔn)秸{(diào)用
LResponse response = interceptor.intercept(realInterceptorChain);
return response;
}
}
然后再定義幾個攔截器和測試類來測試效果:
public class Interceptor1 implements LInterceptor {
@Override
public LResponse intercept(LChain lChain) throws IOException {
LRequest request = lChain.request();
System.out.println("攔截器一攔截request");
LResponse lResponse = lChain.proceed(request);
System.out.println("攔截器一攔截response");
return lResponse;
}
}
public class Interceptor2 implements LInterceptor {
@Override
public LResponse intercept(LChain lChain) throws IOException {
LRequest request = lChain.request();
System.out.println("攔截器二攔截request");
LResponse lResponse = lChain.proceed(request);
System.out.println("攔截器二攔截response");
return lResponse;
}
}
public class Interceptor3 implements LInterceptor {
@Override
public LResponse intercept(LChain lChain) throws IOException {
LRequest request = lChain.request();
System.out.println("攔截器三攔截request");
LResponse lResponse = lChain.proceed(request);
System.out.println("攔截器三攔截response");
return lResponse;
}
}
public class LCallServerInterceptor implements LInterceptor {
@Override
public LResponse intercept(LChain lChain) throws IOException {
System.out.println("真正開始請求網(wǎng)絡(luò)");
return new LResponse();
}
}
public static void main(String[] args) {
List<LInterceptor> interceptors = new ArrayList<>();
interceptors.add(new Interceptor1());
interceptors.add(new Interceptor2());
interceptors.add(new Interceptor3());
interceptors.add(new LCallServerInterceptor());
LRequest originRequest = new LRequest();
LRealInterceptorChain realInterceptorChain = new LRealInterceptorChain(interceptors, originRequest, 0);
try {
realInterceptorChain.proceed(originRequest);
} catch (IOException e) {
e.printStackTrace();
}
}
最后我們運(yùn)行測試類可以看到打印日志如下:
攔截器一攔截request
攔截器二攔截request
攔截器三攔截request
真正開始請求網(wǎng)絡(luò)
攔截器三攔截response
攔截器二攔截response
攔截器一攔截response
其實(shí)你會發(fā)現(xiàn)去掉每個類的L首字母就是okhttp源碼里的類拍谐,這樣單獨(dú)提取出來更容易理解interceptor的責(zé)任鏈的鏈?zhǔn)秸{(diào)用