结合泛型、反射重读Retrofit

1,556 阅读11分钟

前言

看过Retrofit的应该知道,Retrofit的核心技术之一是注解+反射+动态代理,这一篇主要温故Retrofit框架的实现原理,结合上一篇泛型反射相关文章,看一下它是如何处理收集参数的,组装请求的,再到整个流程。

需要了解注解和泛型擦除以及反射获取泛型类型相关的知识点,可以查看 通俗易懂的泛型原理及其相关知识点

目录

一、代理模式

具体分析看 代理模式

静态代理模式(普通、强制)一般会有三种角色

抽象角色:代理角色和真实角色对外提供的公共方法,一般就是接口

真实角色:实现抽象角色的接口,内部实现真正的业务逻辑

代理角色:实现抽象角色的接口,对真实角色进行代理,然后附加自己的操作,集中管理真实角色的处理

使用代理时要清楚代理模式的目的,也就是代理模式的好处,避免了外部直接访问真实对象,只能通过代理对象访问,间接达到访问目标对象,防止带来一些不必要的复杂性,统一在代理模式中调度真实对象。真实对象只关心本职业务逻辑。

项目中假如有一个场景是,实现图片加载时,考虑目前Glid加载图片的替换性,即以后可能会用其它更好的技术A替代它,你如何实现。项目在不断发展,技术也在不断更新,这也是有可能的。

然后直接设置具体的对象,使用时拿到接口对象,像早期组件化通信也会利用这种方法。

但是静态代理也有缺点,在业务开发过程中,每种业务职能对应于一个接口,每个代理类只能实现一个接口,这样写出来的代理类对象偏多,这时候就需要考虑使用动态代理了

动态代理源码分析可以见 代理模式 ,代理模式生成的类存在于内存中,我们不会看到有相关的文件生成。当然想看一下动态代理生成的内容是怎么样的,也不是不可以。

public interface ApiService {
    void get();
    void post();
}
public class TestProxy {
    public static void main(String[] args){
        String name = ApiService.class.getName()+"$Proxy0";
        //源码中生成byte方式
        byte[] bytes = ProxyGenerator.generateProxyClass(name,new Class[]{ApiService.class});
        try {
            FileOutputStream fos = new FileOutputStream("src/" + name + ".class");
            fos.write(bytes);
            fos.close();
        }catch (Exception e){

        }
    }
}

生成了一个demo.ApiService$Proxy0.class 文件,内容如下

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package demo;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;

public final class ApiService$Proxy0 extends Proxy implements ApiService {
    private static Method m1;
    private static Method m4;
    private static Method m2;
    private static Method m3;
    private static Method m0;

    public ApiService$Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final void post() throws  {
        try {
            super.h.invoke(this, m4, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final void get() throws  {
        try {
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    static {
        try {
            m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
            m4 = Class.forName("demo.ApiService").getMethod("post");
            m2 = Class.forName("java.lang.Object").getMethod("toString");
            m3 = Class.forName("demo.ApiService").getMethod("get");
            m0 = Class.forName("java.lang.Object").getMethod("hashCode");
        } catch (NoSuchMethodException var2) {
            throw new NoSuchMethodError(var2.getMessage());
        } catch (ClassNotFoundException var3) {
            throw new NoClassDefFoundError(var3.getMessage());
        }
    }
}

上面 super.h 就是使用动态代理传递的 InvocationHandler , 具体可以查看上面代码。

二、Retrofit

注解 + 反射 + 动态代理

具体使用 Retrofit使用教程二

Retrofit从架构角度来看,本身就相当于一个工厂,将接口数据收集加工后,交给OKHttp处理,然后将返回数据包装后给使用者,能降低代码使用、代码维护风险、提高我们的开发效率,对于数据转换扩展可以和Gson或者RxJava适配。

Retrofit从技术角度来看,精髓在于反射+动态代理+注解+Convert+CallAdapter,后面两个的扩展性,导致可以完美接入RxJavaCallAdapter和自定义Convert解析数据。Convert主要用来转换数据,包括请求参数值和服务器返回的数据。CallAdapter 主要用来组装数据,放入OKHttpCall中,通过其adapt转换成我们期望返回的数据类型,就是接口方法的返回类型,如果使用了RxJavaCallAdapter,将会返回一个被观察者,有数据时通知观察者。网络请求都放在adapt方法内处理了。

1、注解收集

示例 ApiService.java

public interface ApiService {
    @GET("/record")
    <T> Call<BaseResponse<T>> get();

    @POST("/post")
    @FormUrlEncoded
    Call<BaseResponse> post(@Field("key") String value);
}

使用

Retrofit retrofit = new Retrofit.Builder().baseUrl("https://www.xxx.com").build();
ApiService apiService=  retrofit.create(ApiService.class);

我们调用ApiService方法时,会走到动态代理的invoke,也就是目前分析的 create 方法里的动态代理invoke方法

直接从 Retrofitcreate 方法分析

注释 1 和 注释 2 通过判断是否是 Object 的方法、还是Android或是Java系统的方法,可以避免造成无线循环调用,导致栈溢出。

注释 3 处的 loadServiceMethod 才是关键

   ServiceMethod<?> loadServiceMethod(Method method) {
    ServiceMethod<?> result = serviceMethodCache.get(method); // 从Map缓存取
    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;
  }

这个方法会先从Map里面根据 method 方法取出对应的 ServiceMethod 对象,如果没有,则通过 parseAnnotations 方法解析注解收集起来

static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);//注释 1

    Type returnType = method.getGenericReturnType(); // 注释 2 Method 的返回类型
    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);//注释 3
  }

parseAnnotations  注释 1

 static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
  }
  Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit;
      this.method = method;
      this.methodAnnotations = method.getAnnotations();//方法上的注解标记
      this.parameterTypes = method.getGenericParameterTypes();//返回一个Type对象的数组,它以声明顺序表示此Method对象表示的方法的形式参数类型
      this.parameterAnnotationsArray = method.getParameterAnnotations();//获取方法参数上的注解,包括例如call(@Field("xxx) @Field("xxx2") String  key)这种形式
    }

可以看到,这里主要是收集方法、方法上的注解、参数Type类型、参数中所有注解

我们再看一下它的Builderbuild方法

RequestFactory build() {
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);  //这里就是 解析方法上的注解,平常使用Retrofit需要注意的规则,都会在这里校验,例如使用了方法上@FormUrlEncoded,就不能有@Multipart,然后这里还会检查注解内 的  内容正确性
      }

      if (httpMethod == null) {
        throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
      }

      if (!hasBody) {
        if (isMultipart) {
          throw methodError(method,
              "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
        }
        if (isFormEncoded) {
          throw methodError(method, "FormUrlEncoded can only be specified on HTTP methods with "
              + "request body (e.g., @POST).");
        }
      }

      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler<?>[parameterCount];
      for (int p = 0; p < parameterCount; p++) {
        parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);//注释  2
      }

      if (relativeUrl == null && !gotUrl) {
        throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
      }
      if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
        throw methodError(method, "Non-body HTTP method cannot contain @Body.");
      }
      if (isFormEncoded && !gotField) {
        throw methodError(method, "Form-encoded method must contain at least one @Field.");
      }
      if (isMultipart && !gotPart) {
        throw methodError(method, "Multipart method must contain at least one @Part.");
      }

      return

这块主要是检查注解的使用方式是否按Retrofit的规则来,例如参数内不允许有多个 @Url 注解标记,规则具体可以查看 parseParameter 方法。然后将所有结果收集到 ParameterHandlers<?>[] 数组内,相当于一个参数对应于一个ParameterHandler ,里面存放了注解内的值,例如@Field("key")key。所有这些都放在RequestFactory对象中。

当然除了规则校验,收集ParameterHandlers类,还有一个比较重要的,就是convert,在 注释 2 处 parseParameter函数内,有类似这样的代码,下面代码注释 1 处,会从Retrofit中得到Convert,保存到ParameterHandler,在之后的发起请求过程中,会调用对应的convert方法,组装数据。

if (annotation instanceof Query) {
        validateResolvableType(p, type);
        Query query = (Query) annotation;
        String name = query.value();
        boolean encoded = query.encoded();

        Class<?> rawParameterType = Utils.getRawType(type);
        gotQuery = true;
        if (Iterable.class.isAssignableFrom(rawParameterType)) {
          if (!(type instanceof ParameterizedType)) {
            throw parameterError(method, p, rawParameterType.getSimpleName()
                + " must include generic type (e.g., "
                + rawParameterType.getSimpleName()
                + "<String>)");
          }
          ParameterizedType parameterizedType = (ParameterizedType) type;
          Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
          Converter<?, String> converter =
              retrofit.stringConverter(iterableType, annotations); // 注释 1 
          return new ParameterHandler.Query<>(name, converter, encoded).iterable();
        } 

parseAnnotations 注释 2 getGenericReturnType 返回Type类型如下

Method[]  methods =  ApiService.class.getDeclaredMethods();
Type type  = methods[0].getGenericReturnType();
System.out.println(type);
System.out.println(methods[0].getReturnType());

输出
retrofit2.Call<com.demo.hehe.BaseResponse<T>>
interface retrofit2.Call
true

parseAnnotations 方法先会检查返回类型,是否是按它的要求写的,例如返回 void 那肯定是不行的,返回值的写法有很多种,示例代码 ApiService 那样的,使用泛型或者不使用泛型,包括泛型类型的数组都可以,主要通过 Utils.hasUnresolveableType 检查,检查返回Type的每个元素是否符合规则(Type是否是TypeVariableGenericArrayTypeWildcardTypeParameterizedType 具体可以看上篇文章 通俗易懂的泛型原理及其相关知识点)

parseAnnotations 注释 3 开始通过 parseAnnotations 开始解析方法的注解了

 static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);  // 注释 1 这里不分析,如果使用时没指定,那么就只有两个个 Retrofit默认的CallAdapter ->  CompletableFutureCallAdapterFactory 和  ExecutorCallAdapterFactory
    Type responseType = callAdapter.responseType();
    if (responseType == Response.class || responseType == okhttp3.Response.class) {
      throw methodError(method, "'"
          + Utils.getRawType(responseType).getName()
          + "' is not a valid response body type. Did you mean ResponseBody?");
    }
    if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
      throw methodError(method, "HEAD method must use Void as response type.");
    }

    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);//注释 2

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
  }

注释 1 处 的 Adapter,我们后面分析

注释 2 处 的 Converter ,我们后面分析

我们继续看返回类型 HttpServiceMethod 的 这个构造函数,就是把所有信息收集起来了

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

然后动态代理内loadServiceMethod 执行后 是会调用 invoke 方法,传递调用者方法内的参数,即会调用HttpServiceMethodinvoke方法

  @Override ReturnT invoke(Object[] args) {
    return callAdapter.adapt(
        new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
  }

通过OkHttpCallresquestFactory中的参数名 和args中的值对应起来,如果是get请求,则在Url后面拼接起来。至此,收集完了所有参数。这个OkHttpCallRetrofit的,并不是OkHttp的。CallAdapter会将OkHttpCall 包装后返回OkHttpCall对象,然后就进入到了OkHttp请求阶段了。

接下来,你只需关注CallAdapteradapt方法,看看内部具体做了什么。

2、CallAdapter

之前分析HttpServiceMethod 收集注解那里 会去获取CallAdapter

CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);

Android这边的话,兼容Java 8+Android API24 以上,会有两个CallAdapter,分别是CompletableFutureCallAdapterFactoryExecutorCallAdapterFactory

Retrofit创建时,CallAdapter工厂添加的默认类型

@Override List<? extends CallAdapter.Factory> defaultCallAdapterFactories(
    @Nullable Executor callbackExecutor) {
  if (callbackExecutor == null) throw new AssertionError();
  ExecutorCallAdapterFactory executorFactory = new ExecutorCallAdapterFactory(callbackExecutor);
  return Build.VERSION.SDK_INT >= 24
    ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
    : singletonList(executorFactory);
}

createCallAdapter

HttpServiceMethod.java
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
      Retrofit retrofit, Method method) {
    Type returnType = method.getGenericReturnType();
    Annotation[] annotations = method.getAnnotations();
    try {
      //noinspection unchecked
      return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
      throw methodError(method, e, "Unable to create call adapter for %s", returnType);
    }
  }
  Retrofit.java
 public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
  }
    public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");

    int start = callAdapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);//关键代码
      if (adapter != null) {
        return adapter;
      }
    }
......
    throw new IllegalArgumentException(builder.toString());
  }

该方法内部获取CallAdapter关键代码还是在每个CallAdapter内的get方法中。

CompletableFutureCallAdapterFactory

 @Override public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != CompletableFuture.class) { // 返回类型 例如  A<> A是否是 CompleteFuture
      return null;
    }
    if (!(returnType instanceof ParameterizedType)) { // 返回类型 是否是 A<> 这样的
      throw new IllegalStateException("CompletableFuture return type must be parameterized"
          + " as CompletableFuture<Foo> or CompletableFuture<? extends Foo>");
    }
    Type innerType = getParameterUpperBound(0, (ParameterizedType) returnType);
  //innerType 返回类型的上界
    if (getRawType(innerType) != Response.class) { 返回类型的 是否是 Response,即返回值是 ?extend Response 这样的
      // Generic type is not Response<T>. Use it for body-only adapter.
      return new BodyCallAdapter<>(innerType);
    }

    // Generic type is Response<T>. Extract T and create the Response version of the adapter.
    if (!(innerType instanceof ParameterizedType)) {
      throw new IllegalStateException("Response must be parameterized"
          + " as Response<Foo> or Response<? extends Foo>");
    }
    Type responseType = getParameterUpperBound(0, (ParameterizedType) innerType);//获取返回类型 A<T>  T 类型
    return new ResponseCallAdapter<>(responseType);
  }

上面这个一般不会走到,第一步就返回Null了,除非在ApiService接口定义的方法内,返回值是 CompletableFuture 类型的,需要使用到 Future 来操作请求结果,不清楚的可以先去了解Future

DefaultCallAdapterFactory

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

      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }

adapt方法内返回了默认的ExecutorCallbackCall,内部使用代理模式,间接调用了RetrofitOkHttpCall,当OkHttpCall执行完后,会通过CallbackExecutor(内部就是一个主线程Handler)切换到主线程。

  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;
    }

    @Override public void enqueue(final Callback<T> callback) {
      checkNotNull(callback, "callback == null");

      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              if (delegate.isCanceled()) {
                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.
                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
              } else {
                callback.onResponse(ExecutorCallbackCall.this, response);
              }
            }
          });
        }

        @Override public void onFailure(Call<T> call, final Throwable t) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

    @Override public Response<T> execute() throws IOException {
      return delegate.execute();
    }
......
  }

我们最后分析一下CallAdapter 中的 泛型类型,直接看代码注释

public interface CallAdapter<R, T> {
  /**
  * 获取返回值类型,后期通过Convert将服务器返回的数据转换成想要的类型
   */
  Type responseType();

  /**
  *  HttpServiceMethod中invoke调用的方法,也就是每次通过Retrofit都会触发的一个方法,
	*/
  T adapt(Call<R> call);

  abstract class Factory {
    /**
     * Returns a call adapter for interface methods that return {@code returnType}, or null if it
     * cannot be handled by this factory.
     */
    public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
        Retrofit retrofit);

    /**
     * 泛型上界类型
     * example, index 1 of {@code Map<String, ? extends Runnable>} returns {@code Runnable}.
     */
    protected static Type getParameterUpperBound(int index, ParameterizedType type) {
      return Utils.getParameterUpperBound(index, type);
    }

    /**
     *   A<?>  --> A
     * {@code List<? extends Runnable>} returns {@code List.class}.
     */
    protected static Class<?> getRawType(Type type) {
      return Utils.getRawType(type);
    }
  }
}

结合CallAdapter 接口看一下, DefaultCallAdapterFactory 中为什么 直接 new CallAdapter<Object,Call<?>>(){} ,泛型这样写,是有目的的,相当于R -> Object,然后adapt方法内参数就是Call<Object> 返回值经过泛型擦除就行Call<Object> 了,然后直接返回 call 就不会报错。

3、Convert

HttpServiceMethod持有的responseConvert是通过这样获取的,其中responseType是通过CallAdapter获取到的

Converter<ResponseBody, ResponseT> responseConverter =  createResponseConverter(retrofit, method, responseType);

createResponseConverter

 private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
      Retrofit retrofit, Method method, Type responseType) {
    Annotation[] annotations = method.getAnnotations();
    try {
      return retrofit.responseBodyConverter(responseType, annotations);
    } catch (RuntimeException e) { // Wide exception range because factories are user code.
      throw methodError(method, e, "Unable to create converter for %s", responseType);
    }
  }

这个方法内部会根据responseType拿到对应的Convert,在构建Retrofit时,默认添加了BuiltInConverters,它继承自Converter.Factory,我们自己自定义的也是继承自Converter.Factory类。

public interface Converter<F, T> {
  @Nullable T convert(F value) throws IOException;

  abstract class Factory {
   //得到responseConvert时调用,后续通过HttpServiceMethod传递给OkHttpCall
    public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
        Annotation[] annotations, Retrofit retrofit) {
      return null;
    }
   //在处理PartMap或者Par、Body等注解时,会调用,具体见RequestFactory的 parseParameterAnnotation方法
    public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
        Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
      return null;
    }
    //在处理FieldMap等注解是会调用,见  parseParameterAnnotation 方法
    public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
        Retrofit retrofit) {
      return null;
    }
}

常见的GsonConvert如下,Retrofit主要是通过Convert来包装请求参数和将返回数据转换成我们定义的格式

public final class GsonConverterFactory extends Converter.Factory {

  //最常使用的静态工厂方法,使用默认的Gson实例	
  public static GsonConverterFactory create() {
    return create(new Gson());
  }

  //使用这个工厂方法可以从外部传入Gson对象,对Gson对象做配置
  public static GsonConverterFactory create(Gson gson) {
    ...
    return new GsonConverterFactory(gson); // -> implements Converter<T, RequestBody>
  }

  private final Gson gson;
  private GsonConverterFactory(Gson gson) {
    this.gson = gson;
  }

  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonResponseBodyConverter<>(gson, adapter);
  }

  @Override
  public Converter<?, RequestBody> requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonRequestBodyConverter<>(gson, adapter); // -> implements Converter<ResponseBody, T>
  }
}

4、发送请求

我们从第一点末尾,可以了解到发起请求是通过CallAdapteradapt方法出发的,而CallAdapteradapter方法,默认会返回ExecutorCallbackCall ,然后触发它的enqueue 方法,内部真正调用的还是OkHttpCallenqueue方法。

  @Override public void enqueue(final Callback<T> callback) {
    checkNotNull(callback, "callback == null");

    okhttp3.Call call;
    Throwable failure;

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      call = rawCall;
      failure = creationFailure;
      if (call == null && failure == null) {
        try {
          call = rawCall = createRawCall(); //注释 1
      .....
	// OKHttp开始发起请求
    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response<T> response;
        try {
          response = parseResponse(rawResponse); //注释 2
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }

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

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

......
  }

我们关注 注释 1 和 注释 2 处,注释1

  private okhttp3.Call createRawCall() throws IOException {
    okhttp3.Call call = callFactory.newCall(requestFactory.create(args)); //这里是invoke时传递的参数,也就是ApiService.java 中每个方法的形参值
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }

requestFactory.crate 这里截取一部分

 for (int p = 0; p < argumentCount; p++) {
      argumentList.add(args[p]);
      handlers[p].apply(requestBuilder, args[p]);
    }

这里会调用apply方法,apply方法内部就是将参数值和参数名进行匹配,还记得之前Retrofit将注解值和包装参数值的 requestConvert 传递给了RequestFactory吗?这里就是传递参数值,然后构建请求Url或者将参数组装,例如ParmaeterHandler.Path

    @Override void apply(RequestBuilder builder, @Nullable T value) throws IOException {
      if (value == null) {
        throw new IllegalArgumentException(
            "Path parameter \"" + name + "\" value must not be null.");
      }
      builder.addPathParam(name, valueConverter.convert(value), encoded);
    }

注释2 处 parseResponse 方法,就是通过传递给OKHttpCallresponseConvert,调用其convert方法将数据解析成我们想要的类型,然后返回。

  Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();
.......
    try {
      T body = responseConverter.convert(catchingBody);
      return Response.success(body, rawResponse);
    } catch (RuntimeException e) {
      // If the underlying source threw an exception, propagate that rather than indicating it was
      // a runtime exception.
      catchingBody.throwIfCaught();
      throw e;
    }
  }