Retrofit源码剖析

171 阅读15分钟

基本用法

val retrofit = Retrofit.Builder()
                .baseUrl("baseurl")
                .callFactory(xxx)
                .addCallAdapterFactory(xxx)
                .addConverterFactory(xxx)
                .build()
val api = retrofit.creat(Api::class.java)
api.getName("1").enqueue(object:Callback<UserName>{ 

    override fun onFailure(call: Call<UserName>, t: Throwable) {
        t.printStackTrace() 
    } 
    
    override fun onResponse(call: Call<UserName>, response: Response<UserName>) { 
        do something
    }
}


interface Api { 
    @GET("users/{userid}") 
    fun getName(@Path("userid") id: String): Call<UserName>
}

基本用法就不赘述了,下面分析其源码。

源码分析

val retrofit = Retrofit.Builder(). ... .build()这段代码就是通过链式调用实例化retrofit,并根据需要传入一些初始化参数,比如设置baseUrl,添加GsonConverterFactory RxJava3CallAdapterFactory等。

为了便于理解,我们从后面往前看起,从enqueue(object : Callback<ResponseBody>{...}入手。点进enqueue方法:

public interface Call<T> extends Cloneable {
  ...
  void enqueue(Callback<T> callback);
  ...
}

可以看到是接口Call中的方法,这个Call很明显就是我们创建的Api中的方法返回的。我们创建的Api也是接口,所以必然有其实现类,而api实例是通过retrofit.create(Api::class.java)方法返回的,所以可以推断api是在create方法中实现的,我们重点看一下这个create方法。

重点一:Retrofit.create 方法

public final class Retrofit{
...
public <T> T create(final Class<T> service) {
  validateServiceInterface(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 {
              // 如果这个方法是Object中的方法,就不做处理,按原方法执行
              if (method.getDeclaringClass() == Object.class) {
                return method.invoke(this, args);
              }
              args = args != null ? args : emptyArgs;
              return platform.isDefaultMethod(method)
                  ? platform.invokeDefaultMethod(method, service, proxy, args)
                  : loadServiceMethod(method).invoke(args);
            }
          });
}

①处是对传入的Class进行合法性检验,不是重点,这里就不往里看了,重点看下面。这里Retrofit是采用动态代理来返回Api的实例,当外部调用Api中的方法时,代理类会拦截该方法,获取该方法的信息,并执行invoke方法,可以看到invoke方法有一个method参数,这个参数就是外部当前正在调用的Api中的方法。Api中的每个方法都是一个请求,将method作为参数传入loadServiceMethod方法,loadServiceMethod返回一个ServiceMethod实例,然后调用其invoke方法(动态代理类和ServiceMethod有同名方法invoke,为了便于区分,下文中将代理类的invoke方法称为P.invoke,将ServiceMethod的invoke方法称为M.invoke)。下面来看看这两个方法。

重点二:loadServiceMethod(method).invoke(args)方法

先看前半部分loadServiceMethod(method)方法:

public final class Retrofit{
private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
...
ServiceMethod<?> loadServiceMethod(Method method) {
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;

  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
      result = ServiceMethod.parseAnnotations(this, method);
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}
}

该方法返回的是ServiceMethod对象,可以看到Retrofit中维护了一个serviceMethodCache,它是一个Map,用来缓存ServiceMethod。为什么要缓存它我们后面说,可以先思考一下。根据传入的method从缓存map中获取ServuceMothod,如果ServiceMethod不存在,就调用ServiceMethod.parseAnnotations(this, method)方法返回一个实例,并put进缓存map里。点进ServiceMethod.parseAnnotations方法:

abstract class ServiceMethod<T> {
  static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    // ①
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    // ②
    Type returnType = method.getGenericReturnType();
    if (Utils.hasUnresolvableType(returnType)) {
      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);
  }
  // ④
  abstract @Nullable T invoke(Object[] args);
}

记住①处的RequestFactory,后面我们会说到。②处是一些异常处理,不关心,直接看③,这里调用的是HttpServiceMethod.parseAnnotations方法。我们注意到ServiceMethod是个抽象类,在④处定义了M.invoke抽象方法。点进HttpServiceMethod.parseAnnotations方法:

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
 
  static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(Retrofit retrofit, Method method, RequestFactory requestFactory) {
    ...
    if (!isKotlinSuspendFunction) {  // ①
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else ...
  }
  
  @Override
  final @Nullable ReturnT invoke(Object[] args) {
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }
}

发现HttpServiceMethod也是个抽象类,①处判断的是是否是kotlin的挂起函数,这里暂不分析kotlin,只看java。可以看到parseAnnotations方法最终返回的是CallAdapted对象,那么这个CallAdapted就是HttpServiceMethod的实现类了,我们稍后看CallAdapted,先来看看M.invoke方法是如何实现的。在M.invoke方法中,创建了Call类型的变量call并且用new OkHttpCall进行了实例化,这个Call类型就是我们定义Api接口时方法的返回值,而OkHttpCall就是Call的实现类。将call作为参数传入了adapt方法,继续追踪adapt方法:

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
    ...
    protected abstract @Nullable ReturnT adapt(Call<ResponseT> call, Object[] args);
    ...
}

发现adapt方法也是个抽象方法,那么它的实现肯定是在HttpServiceMethod的实现类CallAdapted里了。现在再返回来看CallAdapted:

static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
  private final CallAdapter<ResponseT, ReturnT> callAdapter;

  CallAdapted(
      RequestFactory requestFactory,
      okhttp3.Call.Factory callFactory,
      Converter<ResponseBody, ResponseT> responseConverter,
      CallAdapter<ResponseT, ReturnT> callAdapter) {
    super(requestFactory, callFactory, responseConverter);
    this.callAdapter = callAdapter;
  }

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

发现adapt方法内部直接调用了callAdapter.adapt(call)方法,继续跟进:

public interface CallAdapter<R, T> {
  ...
  T adapt(Call<R> call);

  abstract class Factory {
        public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit);
  }
    ...
}

发现CallAdapter是一个接口,内部除了定义了adapt方法,还创建了抽象类Factory,CallAdapter的实例就是由Factory中的get方法返回的。CallAdapted类中的callAdapter追踪到最后是由从Retrofit中的callAdapterFactories集合里取到的CallAdapter.Factory的实现类中的get方法返回的,该实现类是由开头实例化Retrofit时通过addCallAdapterFactory(xxx)方法传入的(比如我们经常使用的RxJava3CallAdapterFactory,它就是CallAdapter.Factory的一个实现类,作用是支持Rxjava式请求),如果没有调用这个方法传入Factory实现类,那么就会使用默认的DefaultCallAdapterFactory(这里就不展示追踪过程了,有兴趣可以自己去看一下源码)。看一下DefaultCallAdapterFactory是如何实现get方法的:

final class DefaultCallAdapterFactory extends Factory {
    @Nullable
    private final Executor callbackExecutor;

    DefaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
        this.callbackExecutor = callbackExecutor;
    }

    @Nullable
    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
            ...
            return 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));
                }
            };
        }
    }

可以看到get方法最终返回了一个CallAdapter的匿名实现类,adapt方法实现逻辑是判断executor如果是null就直接将参数call返回(还记得这个call是什么吗?往上面翻,adapt方法是在M.invoke方法中被调用的,M.invoke方法中创建了一个OkHttpCall的实例传入了adapt方法中,所以这里的参数call就是OkHttCall对象),否则就new一个ExecutorCallbackCall对象返回。再来看看ExecutorCallbackCall做了什么:

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) {
        Objects.requireNonNull(callback, "callback == null");
        this.delegate.enqueue(new Callback<T>() { ... }
    }
}

ExecutorCallbackCall实现了Call接口,并且持有了一个Call类型的变量delegate,而通过①处构造方法可知,这个delegate就是上面adapt方法的call参数,也就是OkHttCall实例,ExecutorCallbackCall实际上就是OkHttpCall的代理类,其enqueue方法里面实际上还是调用的OkhttpCall类中的enqueue方法。至此我们可以断定具体的网络请求操作就是在OkHttpCall中实现的。

现在我们来回顾一下流程:先创建Retrofit实例,然后调用Retrofit的create方法,将我们定义的Api接口的class作为参数传入,create方法里使用动态代理返回Api的代理类,当外部调用Api中的方法时,代理类会拦截Api方法,调用自己的P.invoke方法,将Api中的方法包装成ServiceMethod类,并调用M.invoke方法(M.invoke方法具体实现是在HttpServiceMethod中),M.invoke方法得到的是Call的实现类OkHttpCall(或者其代理类ExecutorCallbackCall),所以我们调用api中的方法(例如文章开头的api.getName("1"))拿到的是一个OkHttpCall实例,再调用enqueue就会由OkHttpCall进行具体的网络请求操作了。

重点三:OkHttpCall(一)

上面分析到具体的网络请求操作是在OkHttpCall中实现的,那么就来看看OkHttpCall做了什么。从它实例化的地方入手,也就是M.invoke方法中:

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {

  private final RequestFactory requestFactory;
  private final okhttp3.Call.Factory callFactory;
  private final Converter<ResponseBody, ResponseT> responseConverter;
  
  @Override
  final @Nullable ReturnT invoke(Object[] args) {
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }
}

可以看到创建OkHttpCall对象时传入了四个参数,我们需要知道这四个参数都是什么。其中args是通过M.invoke方法传进来的,往上追溯M.invoke方法是在P.invoke方法中被调用的,在P.invoke方法中将自己的参数args传给M.invoke。还记得P.invoke方法的作用吗?当外部调用Api中的方法时,拦截Api中的方法,获取所调用方法的信息,所以这个args就是外部调用Api中方法时所传入的参数的值。

知道了args是什么,然后来看其他三个参数。另三个参数是HttpServiceMethod中声明的成员变量,这三个变量是在它的构造方法中进行赋值的(构造方法中也只有给这三个成员变量赋值的代码),值就是通过构造方法传入进来的,所以这三个成员变量值的来源可以从创建对象处找到。因此来看CallAdapted对象的创建代码(前面说到了HttpServiceMethod是抽象类,CallAdapted是其子类),是在HttpServiceMethod.parseAnnotations方法中:

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {

static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(Retrofit retrofit, Method method, RequestFactory requestFactory) {
  ...
  CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);
  Converter<ResponseBody, ResponseT> responseConverter = createResponseConverter(retrofit, method, responseType);
  okhttp3.Call.Factory callFactory = retrofit.callFactory;
  
  if (!isKotlinSuspendFunction) {
    return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
  } else ...
}

其中

  • requestFactory是直接取的HttpServiceMethod.parseAnnotations方法的参数,其是在其父类ServiceMethodparseAnnotations方法中创建的:

    abstract class ServiceMethod { static ServiceMethod parseAnnotations(Retrofit retrofit, Method method) { // ① RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method); ... return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); }

  • responseConverter是由createResponseConverter方法返回的,createResponseConverter方法里就是获取了Retrofit中的Converter实例,Converter是一个接口,和上面的CallAdapter类似,内部也创建了一个Factory抽象类,通过Factory里的responseBodyConverter方法来返回Converter的实例。Converter最常用的一个实现类是GsonResponseBodyConverter,看着是不是很眼熟,没错,它就是由GsonConverterFactory(Converter.Factory的一个实现类)中的responseBodyConverter方法返回的,GsonConverterFactory就是我们经常在开头实例化Retrofit时通过addConverterFactory(xxx)方法传入的,用来将服务器返回的网络请求结果转换成我们创建的Bean类。

  • callFactory也是获取的Retrofit中的callFactory,它的类型是okhttp3.Call.Factory,是一个接口,它的实现类就是在开头实例化Retrofit时通过callFactory(xxx)方法传入的,如果没有调用该方法传入实现类,则使用okhttp中的默认实现类OkHttpClient

我们这里先打断一下,先来看下RequestFactory的作用。

重点四:RequestFactory

还记得我们上面说过的记住①处的RequestFactory吗,它就是在这里用到的,通过RequestFactory.parseAnnotations方法实例化后,最终它会被传入到OkHttpCall中。来看下RequestFactory是做什么的,点进parseAnnotations方法:

final class RequestFactory {
  static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
  }
  ...
}

很简单,只是new了一个Builder对象并调用了其build方法,Builder是RequestFactory类里的内部类,作用显然就是创建RequestFactory对象了。先看下Builder的构造方法:

static final class Builder {
  ...
  final Retrofit retrofit;
  final Method method;
  final Annotation[] methodAnnotations;
  final Annotation[][] parameterAnnotationsArray;
  final Type[] parameterTypes;
  ...
  
  Builder(Retrofit retrofit, Method method) {
    this.retrofit = retrofit;
    this.method = method;
    this.methodAnnotations = method.getAnnotations();
    this.parameterTypes = method.getGenericParameterTypes();
    this.parameterAnnotationsArray = method.getParameterAnnotations();
  }

构造方法接收了retrofitmethod,retrofit不用说,method就是上面P.invoke方法中传入进来的,也就是Api中的方法实例。可以看到构造方法中调用了method的三个方法,分别是获取method的注解、获取method的参数类型、获取method的参数的注解。看到注解有没有联想到什么?我们在创建Api以及里面的方法时,是不是要使用很多注解?那是不是可以猜到点什么?继续来看Builder的build方法:

static final class Builder {
...
RequestFactory build() {
  for (Annotation annotation : methodAnnotations) {
    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);
}
}

可以看到,build方法里首先对methodAnnotations调用了parseMethodAnnotation方法,根据方法名很容易猜到该方法是解析method的注解,点击去看一下:

private void parseMethodAnnotation(Annotation annotation) {
  if (annotation instanceof DELETE) {
    parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
  } else if (annotation instanceof GET) {
    parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
  } else if (annotation instanceof HEAD) {
    parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
  } else if (annotation instanceof PATCH) {
    parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
  } else if (annotation instanceof POST) {
    parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
  } else if (annotation instanceof PUT) {
    parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
  } else if (annotation instanceof OPTIONS) {
    parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
  } else ...
}

果然没错,正是我们在Api中的方法上使用的注解,在这里拿到注解并进行解析。 后面也就很明了了,解析完method的注解后,后续就使用parseParameter方法解析method的参数,在parseParameter方法中会调用parseParameterAnnotation方法解析method的参数的注解。解析完毕得到method的各项数据后,new一个RequestFactory对象将Builder传入。最后再来看下RequestFactory的构造方法:

RequestFactory(Builder builder) {
  method = builder.method;
  baseUrl = builder.retrofit.baseUrl;
  httpMethod = builder.httpMethod;
  relativeUrl = builder.relativeUrl;
  headers = builder.headers;
  contentType = builder.contentType;
  hasBody = builder.hasBody;
  isFormEncoded = builder.isFormEncoded;
  isMultipart = builder.isMultipart;
  parameterHandlers = builder.parameterHandlers;
  isKotlinSuspendFunction = builder.isKotlinSuspendFunction;
}

这里将retrofit中的baseUrl数据以及builder中解析的method的各项数据赋值给RequestFactory中的成员变量保存下来,等待后续使用。

经过以上分析,我们知道了RequestFactory的作用是对Method进行解析,拿到Method的配置数据(Method就是我们在Api中创建的方法,每个方法就是一个网络请求,每个请求都会根据实际需求使用注解进行配置)并保存到自身中,然后将自身传入到OkHttpCall中。可以说RequestFactory就是网络请求配置数据的载体。

重点三:OkHttpCall(二)

现在再来回过头看OkHttpCall,我们弄清了创建OkHttpCall对象时传入的四个参数都是什么,接下来就要看OkHttpCall中做了什么。上面说到OkHttpCall是Call的实现类,而我们拿到Call以后主要是调用enqueue方法进行网络请求,所以主要看OkHttpCall中是如何实现enqueue的:

final class OkHttpCall<T> implements Call<T> {
...
@Override
public void enqueue(final Callback<T> callback) {
  Objects.requireNonNull(callback, "callback == null");

  okhttp3.Call call;
  Throwable failure;
    ...
    if (call == null && failure == null) {
      try {
          // ①创建call对象
        call = rawCall = createRawCall();
      } catch (Throwable t) {
        throwIfFatal(t);
        failure = creationFailure = t;
      }
    }
  }

  if (failure != null) {
    callback.onFailure(this, failure);
    return;
  }
  ...
  // ②进行网络请求
  call.enqueue(
      new okhttp3.Callback() {
        @Override
        public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
          Response<T> response;
          try {
            response = parseResponse(rawResponse);
          } catch (Throwable e) {
            callFailure(e);
            return;
          }

          try {
            callback.onResponse(OkHttpCall.this, response);
          } catch (Throwable t) {
          }
        }

        @Override
        public void onFailure(okhttp3.Call call, IOException e) {
          callFailure(e);
        }

        private void callFailure(Throwable e) {
          try {
            callback.onFailure(OkHttpCall.this, e);
          } catch (Throwable t) {
          }
        }
      });
}

主要看关键代码,enqueue方法中声明了okhttp3.Call类型的变量call,在①处通过createRawCall方法进行实例化,点进createRawCall方法:

private okhttp3.Call createRawCall() throws IOException {
  okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
  if (call == null) {
    throw new NullPointerException("Call.Factory returned null.");
  }
  return call;
}

发现里面是调用了callFactory.newCall(requestFactory.create(args)方法,callFactory上面我们分析过了,是OkHttpCall构造方法其中的一个参数,这里我们就用它的默认实现类OkHttpClient来看。看一下OkHttpClient中的newCall方法:

public class OkHttpClient implements Cloneable, Call.Factory, WebSocket.Factory {
...
@Override public Call newCall(Request request) {
  return RealCall.newRealCall(this, request, false /* for web socket */);
}
}

该方法接收一个Request类型的参数,该参数是通过requestFactory.create(args)创建的,上面我们分析了RequestFactory的作用是解析并保存网络请求的配置信息等待后续使用,就是在这里使用的,看一下create方法:

okhttp3.Request create(Object[] args) throws IOException {
  ...
  int argumentCount = args.length;
  ...
  RequestBuilder requestBuilder = new RequestBuilder(httpMethod,baseUrl,relativeUrl,headers,contentType,hasBody,isFormEncoded,isMultipart);
  ...
  List<Object> argumentList = new ArrayList<>(argumentCount);
  for (int p = 0; p < argumentCount; p++) {
    argumentList.add(args[p]);
    handlers[p].apply(requestBuilder, args[p]);
  }

  return requestBuilder.get().tag(Invocation.class, new Invocation(method, argumentList)).build();
}

可以看到在create方法中,根据Method的注解信息、参数类型信息、参数的注解信息以及参数值数据,生成一个okhttp3.Request实例并返回,这个okhttp3.Request就是最终完整的网络请求体了。 将okhttp3.Request实例传入到上面的newCall方法中,newCall方法里调用了RealCall.newRealCall方法得到RealCall对象并返回,RealCall是okhttp3.Call的实现类。

现在回到OkHttpCall中的enqueue方法,enqueue方法里的变量call现在已经确定了,是一个RealCall实例,后面就是②处调用call的enqueue方法执行网络请求。至此整个Retrofit流程的源码分析完毕,我们也彻底明白了为什么说Retrofit底层是使用okhttp进行网络请求的。

总结

最后再来总结一下Retrofit的完整流程(retrofit和okhttp中存在同名接口Call,下面称retrofit中的Call为R.Call,okhttp中的Call为ok.Call):

首先创建Retrofit实例retrofit,可根据需要传入①CallFactory ②ConverterFactory等,然后调用retrofit的create方法,获取到Api的动态代理类,每当Api中的方法被调用时,代理类会拦截Api的方法,将其转换成Method对象传入自身的P.invoke方法中,在P.invoke方法中调用ServiceMethod.parseAnnotations(retrofit, method)方法将Method包装成ServiceMethod,并调用其M.invoke方法,M.invoke方法中会创建并返回OkHttpCall对象,OkHttpCall是R.Call(也就是创建Api中的方法时所定义的返回值Call)的实现类。通过M.invoke方法拿到Call对象后,再调用Call的enqueue方法即可进行网络请求。

ServiceMethod中声明了一个RequestFactory类型的变量requestFactory,在parseAnnotations方法中会实例化requestFactory。RequestFactory是Method数据的载体类,里面存储的是Method的方法注解、参数类型、参数的注解等数据,这些数据会在RequestFactory实例化时解析Method对象来得到。在M.invoke方法中创建OkHttpCall的对象时,会将自身(即HttpServiceMethod)中存储的requestFactory callFactory responseConverter以及M.invoke方法的参数args传入到OkHttpCall中。其中callFactory是上面①的实例,responseConverter是上面②的实例,args是Method对象的参数的值。

当调用R.call的enqueue时,实际执行的是OkHttpCall中的enqueue方法,在该方法中声明了ok.Call类型的变量call,通过callFactory.newCall(requestFactory.create(args))方法获取到RealCall对象,RealCall是ok.Call的实现类,获取到RealCall对象后调用其enqueue方法来执行网络请求操作。所以当我们在外部调用R.Call的enqueue方法时,最终实际执行网络请求操作的是ok.Call的enqueue方法。

callFactory.newCall方法接收的是okhttp3.Request类型的参数,这个Request参数就是最终的网络请求体,它是在RequestFactory中的create方法里创建的,RequestFactory在create方法中将Method的方法注解、参数类型、参数的注解和参数的值等数据转化成一个okhttp3.Request对象并返回。

好了流程总结完毕,现在来思考一下上面提过的为什么Retrofit中要缓存ServuceMothod。ServiceMothod是什么? 它是由Method经过包装而来的,Method就是Api中的方法,而Api中的方法就是一个个的网络请求,所以ServiceMothod可以理解为是网络请求的承载体,而一个网络请求可能会被多次发起,所以将ServiceMothod缓存起来,后面再次发起该网络请求时可以立即执行,无需重新创建对象,从而提升性能。