撸Retrofit2源码

本文使用Retrofit-2.6.2源码

切入点:

  • retrofit对象构造

  • new Retrofit.Builder()
                    .baseUrl(Constants.BASE_URL)
                    .client(getOkHttpClient())
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                    .build();
    
  • 调用请求接口retrofit.create(final Class<T> service)


Retrofit对象构造

Retrofit对象构造使用的是构造者模式,主要看retrofit2.Retrofit.Builder类:

public static final class Builder {
    private final Platform platform;
    private @Nullable okhttp3.Call.Factory callFactory;
    private @Nullable HttpUrl baseUrl;
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
    private @Nullable Executor callbackExecutor;
    private boolean validateEagerly;
        ...
  }

Builder主要构造的几个成员变量:

  • platform:Android平台还是非Android平台(Java8)
  • callFactory:实现newCall方法的类,一般是OkHttpClient
  • baseUrl:hostUrl
  • converterFactories:对网络请求对响应进行转化
  • callAdapterFactories;对请求的封装
  • callbackExecutor:Android平台下默认为主线程handler执行
  • validateEagerly:默认为false,为true的时候提前加载请求方法

retrofit.create()

整个Retrofit的使用就是从create方法开始的:

  public <T> T create(final Class<T> service) {
    // 1 监测service请求接口是不是有效的
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      // 2 如果validateEagerly=true,那么预加载请求的方法
      eagerlyValidateMethods(service);
    }
    //3 使用动态代理处理service请求接口
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();
          private final Object[] emptyArgs = new Object[0];

          @Override public @Nullable Object invoke(Object proxy, Method method,
              @Nullable Object[] args) throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }
  1. 注释1处,监测service请求接口是不是有效的:

    • 条件一:service类是一个接口

    • 条件二:service接口中不包含其他子接口

      则认为有效,否则直接抛异常

      static <T> void validateServiceInterface(Class<T> service) {
        if (!service.isInterface()) {
         //如果不是接口直接抛出异常
          throw new IllegalArgumentException("API declarations must be interfaces.");
        }
     
        if (service.getInterfaces().length > 0) {
        // 如果service中包含其他子接口,抛出异常
          throw new IllegalArgumentException("API interfaces must not extend other interfaces.");
        }
      }
    
  1. 注释2处,如果validateEagerly=true,那么预加载请求的方法(默认validateEagerly=false,不会执行这个方法):

      private void eagerlyValidateMethods(Class<?> service) {
        //获取当前的平台,Android端开发的时候是Android()
        Platform platform = Platform.get();
        //遍历接口中的所有方法,挑选不是默认、静态的方法
        for (Method method : service.getDeclaredMethods()) {
          if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {
            // 将挑选出的方法进行包装,加入缓存
            loadServiceMethod(method);
          }
        }
      }
    
  2. 注释3处,使用动态代理处理service请求接口,在动态代理的invoke()方法中实现了请求接口的封装:

    @Override public @Nullable Object invoke(Object proxy, Method method,
                  @Nullable Object[] args) throws Throwable {
    // If the method is a method from Object then defer to normal invocation.
    if (method.getDeclaringClass() == Object.class) {
      // 如果这个方法是继承自object,那么这个方法不做处理,直接返回被代理的方法
     return method.invoke(this, args);
    }
    if (platform.isDefaultMethod(method)) {
     // 默认方法只会在Java8中出现,Android平台上直接会抛异常
     return platform.invokeDefaultMethod(method, service, proxy, args);
    }
      // 4 这里将请求进行封装、加入缓存,最后invoke调用
    return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
    }
    
   
4. 注释4处,将请求进行封装、加入缓存,最后invoke调用:

   ```java
     ServiceMethod<?> loadServiceMethod(Method method) {
       // 在缓存中获取请求方法,如果存在直接返回
       ServiceMethod<?> result = serviceMethodCache.get(method);
       if (result != null) return result;
   
       synchronized (serviceMethodCache) {
         result = serviceMethodCache.get(method);
         if (result == null) {
           // 5 将请求方法进行封装得到一个ServiceMethod对象
           result = ServiceMethod.parseAnnotations(this, method);
           serviceMethodCache.put(method, result);
         }
       }
       return result;
     }
  1. 注释5处,通过ServiceMethod的静态方法parseAnnotations()将请求方法进行封装得到一个ServiceMethod对象:

      static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
        // 将请求方法的注解、参数、参数的注解等提取并生成requestFactory对象
        RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
         // 获取请求方法的返回类型
        Type returnType = method.getGenericReturnType();
        if (Utils.hasUnresolvableType(returnType)) {
          // 如果是不是一个Class的类型或者不是参数化的Class类型,你就抛出异常
          throw methodError(method,
              "Method return type must not include a type variable or wildcard: %s", returnType);
        }
        if (returnType == void.class) {
          // 如果返回类型为空,抛出异常
          throw methodError(method, "Service methods cannot return void.");
        }
    
        return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
      }
    

    parseAnnotations()的RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);这句话将请求方法的注解、参数、参数的注解等提取并生成requestFactory对象:

      static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
        return new Builder(retrofit, method).build();
      }
      
          RequestFactory build() {
          for (Annotation annotation : methodAnnotations) {
          // 这里解析请求方法的注解:请求类型、是否有请求体、请求的url、请求头
            parseMethodAnnotation(annotation);
          }
             ...
          int parameterCount = parameterAnnotationsArray.length;
          parameterHandlers = new ParameterHandler<?>[parameterCount];
            // 逐一解析参数
          for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) {
            parameterHandlers[p] =
                parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
          }
             ...
          return new RequestFactory(this);
        }
    

    到此,完成了请求方法的request部分的封装。但是ServiceMethod对象还缺少返回参数的封装,所有ServiceMethod.parseAnnotations()方法最终调用return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);做后续处理,返回一个完整的ServiceMethod对象。

      static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
          Retrofit retrofit, Method method, RequestFactory requestFactory) {
         // 6 获取请求方法的返回类型
        adapterType = method.getGenericReturnType();
         // 7 通过方法的返回类型去创建callAdapter
        CallAdapter<ResponseT, ReturnT> callAdapter =
            createCallAdapter(retrofit, method, adapterType, annotations);
        // 8 响应的类型
        Type responseType = callAdapter.responseType();
         // 9 构建响应的转换器
        Converter<ResponseBody, ResponseT> responseConverter =
            createResponseConverter(retrofit, method, responseType);
    
        okhttp3.Call.Factory callFactory = retrofit.callFactory;
    
        return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
      }
    

    注释6处,获取请求方法的返回类型,一般情况下是:Call<xxxBean>Observable<xxxBean>这样的封装类型。通过这个返回类型,注释7处得到了callAdapter:

      private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
          Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
         return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
      }
    
    

    这里调用哦那个retrofit类的callAdapter()方法:

      public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
         // 调用nextCallAdapter()方法
        return nextCallAdapter(null, returnType, annotations);
      }
      public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
          Annotation[] annotations) {
        int start = callAdapterFactories.indexOf(skipPast) + 1;
        for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
          // 遍历callAdapterFactories找到合适的callAdapter返回
          CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
          if (adapter != null) {
            return adapter;
          }
        }
      }
    

    callAdapterFactories.get(i).get(returnType, annotations, this)因为callAdapterFactories中可能有多个Factory,且它们的实现都不一样,一下对比两个:

    • DefaultCallAdapterFactory.class

       @Override public @Nullable CallAdapter<?, ?> get(
           Type returnType, Annotation[] annotations, Retrofit retrofit) {
         if (getRawType(returnType) != Call.class) {
           return null;
         }
         final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
      
        return new CallAdapter<Object, Call<?>>() {
           @Override public Type responseType() {
             return responseType;
           }
          @Override public Call<Object> adapt(Call<Object> call) {
             return executor == null
                 ? call
                 : new ExecutorCallbackCall<>(executor, call);
           }
        };
       }
      

      如果返回类型不是Call的包装类型,那么直接返回null。

    • CompletableFutureCallAdapterFactory.class (Java8)

        @Override public @Nullable CallAdapter<?, ?> get(
            Type returnType, Annotation[] annotations, Retrofit retrofit) {
          if (getRawType(returnType) != CompletableFuture.class) {
            return null;
          }
        
          Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType);
          if (getRawType(innerType) != Response.class) {
            // Generic type is not Response<T>. Use it for body-only adapter.
            return new BodyCallAdapter<>(innerType);
          }
          Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType);
          return new ResponseCallAdapter<>(responseType);
        }
      

      如果返回类型的被包装类不是CompletableFuture,那么直接返回null

    最终从callAdapterFactories筛选出合适的Fractory。

    注释8处,获取响应的类型:

    return Utils.getParameterUpperBound(index, type);
    

    注释9处,构建响应的转换器:

      private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
          Retrofit retrofit, Method method, Type responseType) {
        Annotation[] annotations = method.getAnnotations();
        return retrofit.responseBodyConverter(responseType, annotations);
      }
    

    使用的retrofit的responseBodyConverter()方法:

      public <T> Converter<ResponseBody, T> responseBodyConverter(Type type, Annotation[] annotations) {
        return nextResponseBodyConverter(null, type, annotations);
      }
    
      public <T> Converter<ResponseBody, T> nextResponseBodyConverter(
          @Nullable Converter.Factory skipPast, Type type, Annotation[] annotations) {
        checkNotNull(type, "type == null");
        checkNotNull(annotations, "annotations == null");
    
        int start = converterFactories.indexOf(skipPast) + 1;
        for (int i = start, count = converterFactories.size(); i < count; i++) {
          Converter<ResponseBody, ?> converter =
              converterFactories.get(i).responseBodyConverter(type, annotations, this);
          if (converter != null) {
            //noinspection unchecked
            return (Converter<ResponseBody, T>) converter;
          }
        }
      }
    

    responseBodyConverter()方法调用了nextResponseBodyConverter()方法,与之前callAdapter的创建类似,也是从factories中获取合适的Factory然后创建出converter对象。

    最终通过responseConverter 、callAdapter、入参传入的requestFactory以及retrofit.callFactory构造出请求方法独有的HttpServiceMethod对象。

    至此,请求方法的封装过程已经完毕。


    请求调用:ServiceMethod.invoke()

    ServiceMethod是一个抽象类,invoke()方法的实现在它的子类HttpServiceMethod中:

      @Override final @Nullable ReturnT invoke(Object[] args) {
        Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
        return adapt(call, args);
      }
    
      protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
    

    从上面创建HttpServiceMethod的代码可以看出,HttpServiceMethod的实现类为CallAdapted,所以adapt()也是在CallAdapted中实现的:

        @Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
          return callAdapter.adapt(call);
        }
    

    adapt的最终实现有回到了HttpServiceMethod对象的成员变量callAdapter的adapt()方法中了,callAdapter

    接口有多个实现类,这里看两个实现类的adapt:

    • D efaultCallAdapterFactory.call

      new CallAdapter<Object, Call<?>>() {
                      public Type responseType() {
                          return responseType;
                      }
      
                      public Call<Object> adapt(Call<Object> call) {
                          return (Call)(executor == null ? call : new DefaultCallAdapterFactory.ExecutorCallbackCall(executor, call));
                      }
                  }
                  
          static final class ExecutorCallbackCall<T> implements Call<T> {
              final Executor callbackExecutor;
              final Call<T> delegate;
      
              ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
                  this.callbackExecutor = callbackExecutor;
                  this.delegate = delegate;
              }
      
              public void enqueue(final Callback<T> callback) {
                  Utils.checkNotNull(callback, "callback == null");
                  this.delegate.enqueue(new Callback<T>() {
                      public void onResponse(Call<T> call, final Response<T> response) {
                          ExecutorCallbackCall.this.callbackExecutor.execute(new Runnable() {
                              public void run() {
                                  if (ExecutorCallbackCall.this.delegate.isCanceled()) {
                                      callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
                                  } else {
                                      callback.onResponse(ExecutorCallbackCall.this, response);
                                  }
      
                              }
                          });
                      }
      
                      public void onFailure(Call<T> call, final Throwable t) {
                          ExecutorCallbackCall.this.callbackExecutor.execute(new Runnable() {
                              public void run() {
                                  callback.onFailure(ExecutorCallbackCall.this, t);
                              }
                          });
                      }
                  });
              }
          }
      

      这是默认情况的callAdapter,直接在ExecutorCallbackCall中执行call.callback(主线程)。

    • RxJava2CallAdapter

        @Override public Object adapt(Call<R> call) {
          Observable<Response<R>> responseObservable = isAsync
              ? new CallEnqueueObservable<>(call)
              : new CallExecuteObservable<>(call);
      
          Observable<?> observable;
          if (isResult) {
            observable = new ResultObservable<>(responseObservable);
          } else if (isBody) {
            observable = new BodyObservable<>(responseObservable);
          } else {
            observable = responseObservable;
          }
             //添加调度器
          if (scheduler != null) {
            observable = observable.subscribeOn(scheduler);
          }
      
          if (isFlowable) {
            return observable.toFlowable(BackpressureStrategy.LATEST);
          }
          if (isSingle) {
            return observable.singleOrError();
          }
          if (isMaybe) {
            return observable.singleElement();
          }
          if (isCompletable) {
            return observable.ignoreElements();
          }
          return RxJavaPlugins.onAssembly(observable);
        }
      

      通过判断是同步还是异步,创建对应的Observable对象,然后根据类型不同返回不同的Observable对象。

    至此,整个retrofit调用请求的过程全部完成。

    总结

    • Retrofit 库主要使用了运行时注解+动态代理实现对网络请求接口的封装
    • 使用适配器模式对请求的结果进行转换,以实现与不同框架的搭配使用
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容

  • 本文将顺着构建请求对象->构建请求接口->发起同步/异步请求的流程,分析Retrofit是如何实现的。 开始之前,...
    zhuhf阅读 1,584评论 0 10
  • Retrofit 源码解析 简单用法 Retrofit最简单的用法就是定义一个接口,创建Retrofit对象,调用...
    Kingty阅读 746评论 3 14
  • 适配器模式上一篇文章我们已经分析了Retrofit解析注解封装进ServiceMethod的流程,读者在这里要记住...
    andcoder阅读 599评论 0 2
  • Retrofit这个开源库出来也有一定年头了,记得之前还是在V1.0的版本的时候,之前在三月份也写过一个Retro...
    lovejjfg阅读 1,396评论 0 5
  • 开始使用Retrofit 首先先声明一个用于请求的接口 Converter.Factory factory = G...
    zyc_214阅读 338评论 0 0