Retrofit2 源码分析(二)

接着上回,分析过使用Retrofit的流程后,本篇继续分析 Retrofit # create方法(文章末尾附有时序图)

一、Retrofit # Create

create方法中,主要的是 loadServiceMethod 方法分析,其余都在注释中进行的标注(省略部分不重要代码)

 // Retrofit.java
 public  T create(final Class service) {
    //判断是否为 interface 
    validateServiceInterface(service);
    //1, java 动态代理,创建 interface 实例
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[] { service },
        new InvocationHandler() {
        //2,平台,一般为 Android 
          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 {
              
            // .... 省略....

            //主要分析该方法
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }
1.1、 Retrofit # loadServiceMethod

该方法创建 ServiceMethod 实际new的时候,调用的是 ServiceMethod.parseAnnotations 继续分析该方法

// Retrofit.java
ServiceMethod loadServiceMethod(Method method) {
    //1,尝试从缓存中获取
    ServiceMethod result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        //2,解析注解, this = Retrofit ; method:指的是当前调用的方法
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);//进行缓存
      }
    }
    return result;
  }

二、 ServiceMethod # parseAnnotations

该方法主要是对 注解 进行解析,需要注意的有以下几个地方

  • ServiceMethod 为抽象类,包含了上面所调用的 create方法中调用的 invoke 抽象方法。
  • RequestFactory.parseAnnotations(retrofit,method); 该方法,对 method 和参数 注解 进行解析。
  • HttpServiceMethodServiceMethod 子类,下面会对 HttpServiceMethod.parseAnnotations 进行分析。
//ServiceMethod.java
  abstract class ServiceMethod {

  //关键方法
  static  ServiceMethod parseAnnotations(Retrofit retrofit, Method method){

    //1,通过‘RequestFactory’工厂,  解析‘方法注解’
    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.");
    }
    //ServiceMethod 的子类
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

  //抽象方法,在 create 中调用
  abstract @Nullable T invoke(Object[] args);
}

三、RequestFactory.parseAnnotations

接着上面,对 RequestFactory.parseAnnotations 分析。RequestFactory 转译过来是 ‘请求工厂’ , parseAnnotations 方法通过 Builder.build 创建了一个RequestFactory ,只需要看一下 new Builder()、build() 中做了什么操作。

//RequestFactory.java
static RequestFactory parseAnnotations(Retrofit retrofit, Method method) {
    return new Builder(retrofit, method).build();
  }
  • new Builder(retrofit, method) 将传入的参数retrofit、method 进行了解析(具体见注释)
//RequestFactory.java

    Builder(Retrofit retrofit, Method method) {
      this.retrofit = retrofit;
      this.method = method;
      //1,拿到方法注解。例如:@GET、@POST.....
      this.methodAnnotations = method.getAnnotations();
      //2.获取 方法的‘参数’ 类型。例如:int、String....。
      this.parameterTypes = method.getGenericParameterTypes();
      //3.获取 方法参数的‘注解’。 例如: @Query 、@Filed....
      this.parameterAnnotationsArray = method.getParameterAnnotations();
    }
  • 继续看 build(); 方法,该方法主要是对 方法、参数 进行解析
//RequestFactory.java

RequestFactory build() {
    //1,解析 ‘方法注解’
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }
    //.......... 省略一些判断.....

      //2.解析 ‘参数’
      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(); --> parseMethodAnnotation ,该方法见到了我们熟悉的注解,也就是我们在定义接口方法时候,写到方法上的例如:@GET、@POST等等注解 进行解析。
//RequestFactory.java

    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 if (annotation instanceof HTTP) {
        HTTP http = (HTTP) annotation;
        parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
      } else if (annotation instanceof retrofit2.http.Headers) {
        String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
        if (headersToParse.length == 0) {
          throw methodError(method, "@Headers annotation is empty.");
        }
        headers = parseHeaders(headersToParse);
      } else if (annotation instanceof Multipart) {
        if (isFormEncoded) {
          throw methodError(method, "Only one encoding annotation is allowed.");
        }
        isMultipart = true;
      } else if (annotation instanceof FormUrlEncoded) {
        if (isMultipart) {
          throw methodError(method, "Only one encoding annotation is allowed.");
        }
        isFormEncoded = true;
      }
    }
  • build(); --> parseParameter 解析参数。parseParameter - > parseParameterAnnotation 中对具体的参数注解进行了解析
//RequestFactory.java

 private @Nullable ParameterHandler parseParameter(int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
      ParameterHandler result = null;
      if (annotations != null) {

        //重点是这个 for循环
        for (Annotation annotation : annotations) {
          ParameterHandler annotationAction =
              parseParameterAnnotation(p, parameterType, annotations, annotation);
                //..... 省略一些判断.....
          result = annotationAction;
        }
      }
      //..... 省略一些判断.....
      return result;
    }
  • parseParameter - > parseParameterAnnotation 。重点解析 ‘参数注解’的方法,由于篇幅原因,简单分析两个注解。
    可以看到在下面代码中,看到了我们经常使用的注解 @Url、@Query、@Path 在参数中添加的注解,主要是在这个方法中进行解析。
//RequestFactory.java

@Nullable
    private ParameterHandler parseParameterAnnotation(int p, Type type, Annotation[] annotations, Annotation annotation) {
      if (annotation instanceof Url) {

       //........省略了些判断..........
        gotUrl = true;

        if (type == HttpUrl.class
            || type == String.class
            || type == URI.class
            || (type instanceof Class && "android.net.Uri".equals(((Class) type).getName()))) {
          return new ParameterHandler.RelativeUrl(method, p);
        } else {
          throw parameterError(method, p,
              "@Url must be okhttp3.HttpUrl, String, java.net.URI, or android.net.Uri type.");
        }

      } else if (annotation instanceof Path) {

       //........省略了些判断..........
        gotPath = true;

        Path path = (Path) annotation;
        String name = path.value();
        validatePathName(p, name);

        Converter converter = retrofit.stringConverter(type, annotations);
        return new ParameterHandler.Path<>(method, p, name, converter, path.encoded());

      } else 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()
                + ")");
          }
          ParameterizedType parameterizedType = (ParameterizedType) type;
          Type iterableType = Utils.getParameterUpperBound(0, parameterizedType);
          Converter converter =
              retrofit.stringConverter(iterableType, annotations);
          return new ParameterHandler.Query<>(name, converter, encoded).iterable();
        }

       //.... 省略了一些参数注解...
}    

ParameterHandler 包含了对应各个参数注解的内部类,如下图


image.png

到这里,RequestFactory # build() 方法以及分析完毕,该类主要是对请求的方法以及参数及其注解进行解析。

2.1、回到 ServiceMethod#parseAnnotations 继续往下看 return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);

上面经过 RequestFactory 对请求的 方法以及参数 进行了解析,会继续执行到 HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);

//HttpServiceMethod.java

static  HttpServiceMethod parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {

     //.....省略对 kt 支持判断.....
    Annotation[] annotations = method.getAnnotations();
    Type adapterType;

    if (isKotlinSuspendFunction) {
      //.....省略对 kt 支持判断.....
    } else {
        //方法的返回类型,例如:String、int、Resoponse 等
      adapterType = method.getGenericReturnType();
    }

    //请求适配器
    CallAdapter callAdapter =
       createCallAdapter(retrofit, method, adapterType, annotations);
    Type responseType = callAdapter.responseType();
    if (responseType == okhttp3.Response.class) {
      throw methodError(method, "'"
          + getRawType(responseType).getName()
          + "' is not a valid response body type. Did you mean ResponseBody?");
    }
    if (responseType == Response.class) {
      throw methodError(method, "Response must include generic type (e.g., Response)");
    }
    // TODO support Unit for Kotlin?
    if (requestFactory.httpMethod.equals("HEAD") && !Void.class.equals(responseType)) {
      throw methodError(method, "HEAD method must use Void as response type.");
    }

    Converter responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod) new SuspendForResponse<>(requestFactory,
          callFactory, responseConverter, (CallAdapter>) callAdapter);
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod) new SuspendForBody<>(requestFactory,
          callFactory, responseConverter, (CallAdapter>) callAdapter,
          continuationBodyNullable);
    }
  }

注:忽略对Kt 的分析

该方法中,需要注意的是 createCallAdapter 方法,往下看

//HttpServiceMethod.java
CallAdapter callAdapter = createCallAdapter(retrofit, method, adapterType, annotations);

//HttpServiceMethod.java
  private static  CallAdapter createCallAdapter(
      Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
    try {
      //noinspection unchecked
      return (CallAdapter) 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
//注意该  代表的是 Response, Return 类型
 public CallAdapter callAdapter(Type returnType, Annotation[] annotations) {
    return nextCallAdapter(null, returnType, annotations);
  }

2.2 在分析nextCallAdapter 之前,先解释一下 callAdapterFactories 请求适配器工厂

//Retrofit.java
 public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      callAdapterFactories.add(Objects.requireNonNull(factory, "factory == null"));
      return this;
    }

例如:一般我们项目适配了RxJava的时候,会调用下面方法,来进行 Call 的转换,将Call 转换成 Observable

  addCallAdapterFactory(RxJava2CallAdapterFactory.create())

Retrofit -> build() 方法中,添加了默认的CallAdapter,也就是 DefaultCallAdapterFactory 默认返回的是 Call

//Retrofit.java
public Retrofit build() {
      //........
      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // 添加默认调用适配器。
      List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

      // Make a defensive copy of the converters.
      List converterFactories = new ArrayList<>(
          1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

     //..............
      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }
  }

默认的CallAdapter

 //Platform.java
  List defaultCallAdapterFactories(
      @Nullable Executor callbackExecutor) {
    DefaultCallAdapterFactory executorFactory = new DefaultCallAdapterFactory(callbackExecutor);
    //默认支持 java 8,有2个默认Factory
    return hasJava8Types
        ? asList(CompletableFutureCallAdapterFactory.INSTANCE, executorFactory)
        : singletonList(executorFactory);
  }

2.3继续跟到 Retrofit # nextCallAdapter

//Retrofit.java

   public CallAdapter nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    //....

    //skipPast = null, 那么 start = 1
    //由于SDK>24 支持 java8,则默认的callAdapterFactories.size(); = 2
    int start = callAdapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      // 注意这里的 get,在没有别的CallAdapter 实际是调用的DefaultCallAdapterFactory # get
      CallAdapter adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }

    //省略....
  }

注意 nextCallAdapter中 for循环,调用get方法,当用户没有手动添加 CallAdapter 的时候,调用的是DefaultCallAdapterFactory#get() 返回的是 ExecutorCallbackCall

分析完请求适配器createCallAdapter ,继续看2.1、 ServiceMethod#parseAnnotations

//HttpServiceMethod.java
  static  HttpServiceMethod parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
  //....省略

    //拿到 Call 适配器
    CallAdapter callAdapter =createCallAdapter(retrofit, method, adapterType, annotations);

    // 返回值类型
    Type responseType = callAdapter.responseType();
    
    //... 省略一些判断

    //返回值,转换
    Converter responseConverter = createResponseConverter(retrofit, method, responseType);

    //省略.. 下面会继续分析
2.4 数据转换器 createResponseConverter,其实这里和上面分析CallAdapter 流程差不多,具体如下:
//HttpServiceMethod.java
 private static  Converter 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);
    }
  }

//Retrofit.java 
  public  Converter responseBodyConverter(Type type, Annotation[] annotations) {
    return nextResponseBodyConverter(null, type, annotations);
  }

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

    //.......省略
  }

converterFactories 转换工厂,将返回值,进行转换例如:

//使用:
 .addConverterFactory(FastJsonConverterFactory.create())//数据 fastJson 转换器

//Retrofit.java 
public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(Objects.requireNonNull(factory, "factory == null"));
      return this;
    }

也在Retrofit ->build()中有默认值为:

//Retrofit.java 
public Retrofit build() {
    //...省略

      // Make a defensive copy of the converters.
      List converterFactories = new ArrayList<>(
          1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

      // Add the built-in converter factory first. This prevents overriding its behavior but also
      // ensures correct behavior when using converters that consume all types.
      converterFactories.add(new BuiltInConverters());//内部转换器
      converterFactories.addAll(this.converterFactories); //用户添加的数据转换器
      converterFactories.addAll(platform.defaultConverterFactories());

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }

//PlatForm.java
 List defaultConverterFactories() {
    return hasJava8Types
        ? singletonList(OptionalConverterFactory.INSTANCE)
        : emptyList();
  }

分析完CallAdapter、Converter , 继续看2.1 HttpServiceMethod # parseAnnotations

//HttpServiceMethod.java
  static  HttpServiceMethod parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    //......
    CallAdapter callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
    Type responseType = callAdapter.responseType();
 
    Converter responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;

    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } 
    //忽略 kt分析
  }

该方法在不支持kt情况下,返回CallAdaptedCallAdapted 继承自HttpServiceMethod

//HttpServiceMethod.java
 static final class CallAdapted extends HttpServiceMethod {
    private final CallAdapter callAdapter;

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

    @Override protected ReturnT adapt(Call call, Object[] args) {
     //注意,这里的 callAdapter 是,DefaultCallAdapterFactory
      return callAdapter.adapt(call);
    }
  }

HttpServiceMethod 继承自 ServiceMethod

abstract class HttpServiceMethod extends ServiceMethod{
...

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

注意:在Retrofit->create() 调用的是 ServiceMethod # invoke 方法,最终调到了 HttpServiceMethod # invokeinvoke -> adapt()

//Retrofit.java
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);

到这里Retrofit # create() 方法分析完毕。时序图如下:

SequenceDiagram1.jpg

你可能感兴趣的:(Retrofit2 源码分析(二))