美文网首页
高仿okhttp手写责任链模式

高仿okhttp手写责任链模式

作者: 陈科比大宝贝儿 | 来源:发表于2021-03-16 20:16 被阅读0次

okhttp使用的设计模式面试的时候经常被问到,其中里面最多的建造者模式和责任链模式
其中责任链模式也是okhttp的核心。

  • 创建一系列拦截器,并将其放入到一个拦截器list当中。
  • 创建一个拦截器链RealInterceptorChain对象,并执行拦截器的proceed方法(创建下一个拦截器)。
  • 在发起请求前对request进行处理。
  • 调用下一个拦截器,获取response。
  • 对response进行处理,返回给上一个拦截器。
Response response = getResponseWithInterceptorChain(); 通过拦截器获取一个响应。
007S8ZIlly1ghbgbi291zj30is0ieq45.jpg

okhttp具体实现如何,主要代码:
RealInterceptorChain

 public Response proceed(Request request, Transmitter transmitter, @Nullable Exchange exchange)
      throws IOException {
    if (index >= interceptors.size()) throw new AssertionError();

    calls++;

    // If we already have a stream, confirm that the incoming request will use it.
    if (this.exchange != null && !this.exchange.connection().supportsUrl(request.url())) {
      throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
          + " must retain the same host and port");
    }

    // If we already have a stream, confirm that this is the only call to chain.proceed().
    if (this.exchange != null && calls > 1) {
      throw new IllegalStateException("network interceptor " + interceptors.get(index - 1)
          + " must call proceed() exactly once");
    }

    // Call the next interceptor in the chain.
    RealInterceptorChain next = new RealInterceptorChain(interceptors, transmitter, exchange,
        index + 1, request, call, connectTimeout, readTimeout, writeTimeout);
    Interceptor interceptor = interceptors.get(index);
    Response response = interceptor.intercept(next);

具体拦截器代码:调用proceed方法。

@Override public Response intercept(Chain chain) throws IOException {
   Response networkResponse = chain.proceed(requestBuilder.build());
}

手动实现:

interface  InterceptorCallBack {

    fun handle(chain: Chain):String? //类似于intercept方法

    interface Chain {
        fun proceed(requestStr: String?): String?
        fun getRequest():String?
    }
}

拦截器调度中心


package com.learn.ckx_test.response_chain_demo

//管理类
class RealInterceptorChain:InterceptorCallBack.Chain {

    private val mList: MutableList<InterceptorCallBack>? = ArrayList()
    private var index = 0
    private var lastResponse:String? = ""

    fun addLeaders(leader: InterceptorCallBack) {
        mList?.add(leader)
    }

    fun removeLeaders(leader: InterceptorCallBack) {
        mList?.remove(leader)
    }

    override fun proceed(request: String?): String? {
        lastResponse = request
        println("index的值:$index")
        if (mList == null ||mList.size == 0)  return lastResponse
        if (index >= mList.size) return lastResponse

        val nextIntIterator = mList[index]

        index ++
        println("lastResponse的值:$lastResponse")

        lastResponse = nextIntIterator.handle(this)
        return lastResponse
    }

    override fun getRequest(): String? {
        return lastResponse
    }
}

拦截器1:

class InterceptorOne : InterceptorCallBack {
    
    override fun handle(chain: InterceptorCallBack.Chain): String? {
        println("我Leader1处理过了,传给下一个拦截器")
        val request = chain.getRequest()
        val result = request + "我Leader1处理过了,传给下一个拦截器"
        val response = chain.proceed(result)
        return response
    }
}

拦截器2:

class InterceptorTwo : InterceptorCallBack {
    
    override fun handle(chain: InterceptorCallBack.Chain): String? {

        println("我Leader2处理过了,传给下一个拦截器")
        val request = chain.getRequest()
        val result = request + "我Leader2处理过了,传给下一个拦截器"
        val response = chain.proceed(result)
        return response
    }
}

测试:

  @JvmStatic
    fun main(args: Array<String>) {
        val leaderManager = RealInterceptorChain();//传递下发任务可执行等级
        leaderManager.addLeaders(InterceptorOne());
        leaderManager.addLeaders(InterceptorTwo());
        val result = leaderManager.proceed("开始请求了");//开始执行
        println("最后的结果是:$result")

    }

传入一个requet请求,一定要注意返回response,每个拦截器都能对请求进行处理,处理之后把结果返回给下一个拦截器。
测试结果:

ndex的值:0
lastResponse的值:开始请求了
我Leader1处理过了,传给下一个拦截器
index的值:1
lastResponse的值:开始请求了我Leader1处理过了,传给下一个拦截器
我Leader2处理过了,传给下一个拦截器
index的值:2
最后的结果是:开始请求了我Leader1处理过了,传给下一个拦截器我Leader2处理过了,传给下一个拦截器

注意:

  • 一般网上的例子都是基于递归,在递归里面进行判断是否要往下进行,实际okhttp是在调度中心,根据拦截器集合index判断是否是最后一个拦截器,来终止往下传递。
  • 拦截器传递到最后一定要返回执行后的结果,就像okhttp使用责任链模式执行各个拦截器功能之后,最后一定要返回response才能完整。

相关文章

  • 高仿okhttp手写责任链模式

    okhttp使用的设计模式面试的时候经常被问到,其中里面最多的建造者模式和责任链模式其中责任链模式也是okhttp...

  • Okhttp3 Interceptor(三)

    前言 OkHttp 中的 Interceptor 是通过责任链模式来设计的, 责任链模式参考: 责任链模式 , 至...

  • OkHttp设计模式剖析(三)策略模式

    上一篇 OkHttp设计模式剖析(二)责任链模式 下一篇 OkHttp设计模式剖析(四)享元模式 OKHTTP...

  • 责任链模式与 OkHttp

    什么是责任链模式 OkHttp中责任链模式的实现 一、什么是责任链模式 使多个对象都有机会处理请求,从而避免了请求...

  • 责任链模式及OkHttp中的实现

    责任链模式及OkHttp中的实现 责任链模式 责任链模式是对一个事件的处理方法,所有能对事件进行处理的对象按顺序形...

  • okhttp网络框架源码浅析(二)

    okhttp网络框架源码浅析(一) interceptors责任链 不清楚责任链设计模式,可以先了解一下责任链设计...

  • OkHttp设计模式剖析(一)建造者模式

    下一篇 OkHttp设计模式剖析(二)责任链模式 OKHTTP: 由大名鼎鼎的Square公司开发的网络通信库。...

  • okhttp和责任链模式

    OkHttp—拦截器这篇文章讲了拦截器,今天就谈谈责任链模式责任链模式,其实就是把request通过一系列Inte...

  • 责任链模式

    概念   说到责任链模式,我就想起了okHttp中设置拦截器的时候了,今年、中外、开花,关注。  其实责任链就是将...

  • 从OKHttp源码中看责任链模式

    上篇文章简单理解责任链模式只做了Demo,这篇文章就结合OKHttp的框架来具体看看责任链模式,没看过上篇文章的建...

网友评论

      本文标题:高仿okhttp手写责任链模式

      本文链接:https://www.haomeiwen.com/subject/efxjcltx.html