OKHTTP 源码分析(3)责任链模式

序 、最近几天心情不太美丽 。

 

源码

调用 OKHTTP 最后返回 Response ,当然要看责任链模式 。无论是异步还是同步 ,都需要通过责任链调用得到 Response 。

RealCall 类 :

  Response getResponseWithInterceptorChain() throws IOException {
    // Build a full stack of interceptors.
    List<Interceptor> interceptors = new ArrayList<>();
    interceptors.addAll(client.interceptors()); //首先添加的是用户添加的全局拦截器
    interceptors.add(retryAndFollowUpInterceptor);//错误、重定向拦截器
    //桥接拦截器,桥接应用层与网络层,添加必要的头
    interceptors.add(new BridgeInterceptor(client.cookieJar()));
    //缓存处理,Last-Modified、ETag、DiskLruCache
    interceptors.add(new CacheInterceptor(client.internalCache()));
    //连接拦截器
    interceptors.add(new ConnectInterceptor(client));
    //从这就知道,通过okHttpClient.Builder#addNetworkInterceptor()传进来的拦截器只对非网页的请求生效

    if (!forWebSocket) {
      interceptors.addAll(client.networkInterceptors());
    }
     //真正访问服务器的拦截器
    interceptors.add(new CallServerInterceptor(forWebSocket));

    Interceptor.Chain chain = new RealInterceptorChain(interceptors, null, null, null, 0,
        originalRequest, this, eventListener, client.connectTimeoutMillis(),
        client.readTimeoutMillis(), client.writeTimeoutMillis());

    return chain.proceed(originalRequest);
  }

PS:一共可以看到六个拦截器 。顺序是重定向拦截器 、桥拦截器 、缓存拦截器 、连接拦截器 、网络拦截器 、访问服务拦截器 。为什么我会这样写呢 ?不瞒你说 ,曾经有个面试官问过我这个问题(请说一下OKHTTP中有几个拦截器 ,并且说明拦截器的顺序) 。哈哈哈哈 、、、

 

责任链模式

顾名思义是为请求创建了一个接受者对象的链 。这种模式给予请求的类型 ,对请求的发送者和接受者进行解耦 。在这种模式中通常每个接受者都会包含对另一个接受者的引用 ,如果一个对象不能处理该请求 ,那么他会把相同的请求传递给下一个接收者 ,以此类推 。(有没有想起来 View 的事件分发)

特点

责任链模式可以使请求能被多个对象依次进行处理 ,从而使这些形象形成一条完成的链路 。这样就会使请求由起始点 ,顺着这条链路 ,依次向下一个对象进行传递 ,直至传递到最后一个对象 。

场景

1.当一个请求可能会被某个环节修改 ,并且该环节修改请求后 ,会将该请求继续下发给下一个环节 。

2.请求处理环节可能会发生改变 ,有可能改变其中某个环节 ,也有可能所有的流程发生更新 。比如网络请求 ,将网络请求环节中的重定向 、重试 、拦截器以模块的形式进行责任链连接 。

直接上示例代码 基础写法

1.责任链父类

public abstract class BaseChain {

    //判断当前任务节点 有没有能力执行
    private boolean isDoChain = false;

    public BaseChain(boolean isDoChain) {
        super();
        this.isDoChain = isDoChain;
    }

    // 执行下一个节点
    private BaseChain nextChain;

    // 添加下一个节点任务
    public void addNextChain(BaseChain nextChain) {
        this.nextChain = nextChain;
    }

    // 子任务节点 执行
    public abstract void doAction();



    public void action() {
        if (isDoChain) {
            doAction(); // 执行
        } else {
            if(nextChain != null)nextChain.action(); //继续执行下一个任务
        }
    }


}

2.子节点 Chain1 、Chain2 、Chain3 

public class Chain1 extends BaseChain{


    public Chain1(boolean isDoChain) {
        super(isDoChain);
    }

    @Override
    public void doAction() {
        //执行子节点
        Log.i("Chain","这是 Chain 1 ,老哥");
    }
}

3. 调用 

   private void initChain() {
        Chain1 chain1 = new Chain1(false);
        Chain2 chain2 = new Chain2(false);
        Chain3 chain3 = new Chain3(true);
        Chain4 chain4 = new Chain4(false);

        chain1.addNextChain(chain2);
        chain2.addNextChain(chain3);
        chain3.addNextChain(chain4);

        chain1.action();
    }

打印结果

2020-07-28 16:48:39.459 3539-3539/com.developers.myapplication I/Chain: 这是 Chain 3 ,老哥

跟 OKHTTP 类似的写法

1.接口

public interface IBaseTask {
    
    /**
     *
     * @param isTask 任务节点是否有能力执行
     * @@param iBaseTask 下一个任务节点
     */
    public void doRunAction(String isTask, IBaseTask iBaseTask);


}

2.责任链管理类

public class ChainManager implements IBaseTask {

    private List<IBaseTask> iBaseTaskList = new ArrayList<>();

    //添加子节点
    public void addTask(IBaseTask iBaseTask) {
        iBaseTaskList.add(iBaseTask);
    }

    //索引
    private int index = 0;


    //执行
    @Override
    public void doRunAction(String isTask, IBaseTask iBaseTask) {

        if (iBaseTaskList.isEmpty()) return; //抛异常

        if (index == iBaseTaskList.size() || index > iBaseTaskList.size()) {
            return;
        }

        IBaseTask iBaseTaskResult = iBaseTaskList.get(index);// t1

        index ++;

        iBaseTaskResult.doRunAction(isTask,iBaseTask);

    }
}

3.子节点 Chain1 、Chain2 、Chain3 

public class Chain_1 implements IBaseTask {

    @Override
    public void doRunAction(String isTask, IBaseTask iBaseTask) {
        if ("ok1".equals(isTask)) {
            Log.i("Chain", "任务节点一 ,处理了 。老哥");
            return;
        } else {
            iBaseTask.doRunAction(isTask, iBaseTask);
        }
    }
}

4.调用

  private void initChain2() {
        ChainManager chainManager =new ChainManager();
        chainManager.addTask(new Chain_1());
        chainManager.addTask(new Chain_2());
        chainManager.addTask(new Chain_3());
        chainManager.addTask(new Chain_4());

        chainManager.doRunAction("ok",chainManager);


    }

上述代码示例跟 OKHTTP 的责任链实现思路是一致的,可以说是简化版的 OKHTTP 的责任链 。

 

本来想在分析一下 OKHTTP 的责任链源码 。

大概能看到 index +1 ,做自循环操作 。

 

 

。。。
Wait

。。。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值