今天我们来自己实现一个类似于okhttp里的interceptor功能
定义实体和拦截器接口:
请求实体:
public class LRequest {
}
返回实体:
public class LResponse {
}
拦截器:
public interface LInterceptor {
LResponse intercept(LChain lRequest) throws IOException;
interface LChain {
LRequest request();
LResponse proceed(LRequest request) throws IOException;
}
}
然后定义递归调用的实现类:
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);
//这里触发了下一个拦截,产生了链式调用
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("真正开始请求网络");
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();
}
}
最后我们运行测试类可以看到打印日志如下:
拦截器一拦截request
拦截器二拦截request
拦截器三拦截request
真正开始请求网络
拦截器三拦截response
拦截器二拦截response
拦截器一拦截response
其实你会发现去掉每个类的L首字母就是okhttp源码里的类,这样单独提取出来更容易理解interceptor的责任链的链式调用
网友评论