简析Retrofit的工作原理

注:当前分析的Retorfit版本为2.6.2

Retrofit初始化

一般使用retrofit的时候都是下面这段代码

  public static final String API_URL = "https://api.github.com";
  ......
 Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(API_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();

通过Retrofit的内部类Builder(builder模式)配置baseURL(一般是所有网络Api地址的公共部分);配置转换器工厂ConverterFactory(其作用是将网络请求的请求体requestBody和响应体responseBody做转换,比如GsonConverterFactory创建的GsonRequestBodyConverter将请求参数转换成MediaType为"application/json; charset=UTF-8"的RequestBody,GsonResponseBodyConverter则将OkHttp网络请求的ResponseBody通过Gson反序列化成实体类);配置client(默认采用OkHttp);配置请求适配工厂CallAdapterFactory(其作用是将Retrofit对象的create方法创建Call<R>类型转换成另一种类型,R一般为返回值的实体类类型。比如通过RxJava2CallAdapterFactory创建的RxJava2CallAdapter通过接口CallAdapteradapt方法将Call<R>类型转换成io.reactivex.Observable<retrofit2.Response<R>>类型,);配置回调接口在那个线程执行callbackExecutor(Executor executor)(即retrofit的回调方法retrofit2.Callback<T>,android默认是在主线程);配置callFactory callFactory(okhttp3.Call.Factory factory)(即自定义call);配置validateEagerly(boolean validateEagerly)用于是否在用Retrofitcreate创建代理对象而不是在调用代理对象的方法的时候就开始校验Api接口中申明的所有方法时候合法。然后通过Builder的build方法返回一个Retrofit实例,重点关注一下build方法的逻辑。

    public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
         //platform.defaultCallbackExecutor()返回的是MainThreadExecutor
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
       //platform.defaultCallAdapterFactories()在SDK版本大于等于24的时候
       //返回集合[CompletableFutureCallAdapterFactory,DefaultCallAdapterFactory]
       //否则返回集合[DefaultCallAdapterFactory]
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> 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.
      //内置BuiltInConverters,排在最前的符合要求converter会先用到,方式用户定义了一个一模一样的convert
      converterFactories.add(new BuiltInConverters());
      //用户配置的自定义Converter
      converterFactories.addAll(this.converterFactories);
      //platform.defaultConverterFactories()在SDK版本大于等于24返回OptionalConverterFactory,主要是针对java8的Optional<T>否则返回空
      converterFactories.addAll(platform.defaultConverterFactories());

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

可以看到就是配置参数给Retrofit构造函数传值,下面进入代理对象创建环节。

创建接口的代理对象

注:例子引用了 samples

  //实体类定义
    public static class Contributor {
        public final String login;
        public final int contributions;

        public Contributor(String login, int contributions) {
            this.login = login;
            this.contributions = contributions;
        }
    }
   //接口定义
    public interface GitHub {
        @GET("/repos/{owner}/{repo}/contributors")
        Call<List<Contributor>> contributors(
                @Path("owner") String owner,
                @Path("repo") String repo);
    }
  //关键点,创建代理对象
 GitHub github = retrofit.create(GitHub.class);
 //调用代理对象方法,如果没有在Retrofit的builder方法中配置 
//.addCallAdapterFactory(RxJava2CallAdapterFactory.create())则返回的是Call<T>
 Call<List<Contributor>> call = github.contributors("square", "retrofit");
  // 网络请求返回数据
     List<Contributor> contributors = call.execute().body();
      for (Contributor contributor : contributors) {
          System.out.println(contributor.login + " (" + contributor.contributions + ")");
   }

下面分析关键代码retrofit.create(GitHub.class),跟进去看一下,此处一些校验方法没有列出代码,注释了启作用

package retrofit2;
public final class Retrofit {    
public <T> T create(final Class<T> service) {
    //校验service类格式,service必须是接口类型,并且不能继承自其他接口
    Utils.validateServiceInterface(service);
    //Retrofit的builder类的validateEagerly方法配置,默认为false
    if (validateEagerly) {
     //主要是校验service类中所申明的方法不能是default方法(java 8中interface引入了default方法)
     //同时不能是静态方法,如果满足要求,则调用loadServiceMethod方法
      eagerlyValidateMethods(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.
            //如果是调用的继承自Object方法(比如toString();hashCode(),wait(),notify,getClass())则普通调用,
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            //如果是java8的默认方法
            if (platform.isDefaultMethod(method)) {
                //调用invokeDefaultMethod,实际实现是抛出UnsupportedOperationException异常
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            //核心代码,API接口申明的那些方法
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }
}

方法调用

通过上面的代码可以看到当调用接口API的方法实际上是通过动态代理回调方法里面调用的是ServiceMethod的invoke方法,先跟进ServiceMethod<?> loadServiceMethod(Method method),看看是怎么查找的,后面我们再回来看ServiceMethodinvoke(Object[] args)方法的实现逻辑

package retrofit2;
abstract class ServiceMethod<T> {
 
 static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    //生成RequestFactory的parseAnnotations方法会解析方法的注解,以及方法中的参数的注解,先跳过
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    Type returnType = method.getGenericReturnType();
    //Utils.hasUnresolvableType方法判断Method的返回值类型不能是泛型,泛型数组,通配符,
    //即类似于List<?>,List<?>[],List<T>,List<T>[](T为接口定义中的未指明具体类型参数)
    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.");
    }
    //调用HttpServiceMethod的parseAnnotations,依然是解析接口方法上的注解,生成ServiceMethod
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }
}

先列出Utils类的hasUnresolvableType(@Nullable Type type)方法逻辑分析,因为多处会用到它

package retrofit2;
final class Utils {
    ...
    //判断是否不可解析类型
static boolean hasUnresolvableType(@Nullable Type type) {
    //如果是不是泛型,可以解析
    if (type instanceof Class<?>) {
      return false;
    }
    //如果是参数化类型,递归遍历里面具体的元素类型,比如List<Map<String,Integer>>类型是可以解析的,而
    //List<Map<K,V>>或者List<Map<K,?>>或者List<Map<K,?extends Number>>是无法解析的
    if (type instanceof ParameterizedType) {
      ParameterizedType parameterizedType = (ParameterizedType) type;
      for (Type typeArgument : parameterizedType.getActualTypeArguments()) {
        if (hasUnresolvableType(typeArgument)) {
          return true;
        }
      }
      return false;
    }
    //如果是泛型数组比如List<String>[],List<?>[],List<T>[]这种,List<String>[]是可以解析的,而List<?>[],List<T>[]则不可以
    if (type instanceof GenericArrayType) {
        //校验数组的元素的类型
      return hasUnresolvableType(((GenericArrayType) type).getGenericComponentType());
    }
    //List<T>这种不可以解析
    if (type instanceof TypeVariable) {
      return true;
    }
    //List<?>这种不可以解析
    if (type instanceof WildcardType) {
      return true;
    }
    String className = type == null ? "null" : type.getClass().getName();
    throw new IllegalArgumentException("Expected a Class, ParameterizedType, or "
        + "GenericArrayType, but <" + type + "> is of type " + className);
  }
  ...
}

接着分析RequestFactory.parseAnnotations(Retrofit retrofit, Method method)代码逻辑

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

貌似很简单,就是通过builder模式创建了一个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();
    }
}

可以看到构造方法中透传了Retrofit,要解析的Method,获取标注在方法上的所有注解,方法所有参数(带泛型)类型,参数的注解。注意Method的getParameterTypes()getGenericParameterTypes区别在于,比如List<String>类型参数,前者通过Type的getTypeName得到的是java.util.List后者得到的是java.util.List<java.lang.String>。接着跟进builder类的build方法

package retrofit2;
final class RequestFactory {
      //省略其他代码
    
    
     RequestFactory build() {
      //遍历修饰方法的注解,只解析Retrofit支持的那几个注解    
      for (Annotation annotation : methodAnnotations) {
        //解析方法上的HTTP注解 ,后面分析 
        parseMethodAnnotation(annotation);
      }
      //没有找到Retrofit支持的那几个用于HTTP请求的注解,抛出异常   
      if (httpMethod == null) {
        throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
      }
     //如果不带请求体,只有PATCH,POST,PUT方法才带有请求体,说明不能在方法上用了@DELETE,@HEAD,@GET,@OPTIONS注解后又用@Multipart,@FormUrlEncoded注解
     //具体规范参考HTTP协议
    //hasBody,isMultipart,isFormEncoded的判断在上面的parseMethodAnnotation中完成
      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).");
        }
      }
      //针对带有注解的参数,创建对应的参数处理器ParameterHandler
      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);
      }
    //relativeUrl ,gotUrl,gotField,gotPart的判断在parseParameter方法中完成
      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 new RequestFactory(this);
    }
    
     //省略其他代码
}

总结一下就是build方法会去扫描api接口中方法的注解参数的注解,保证符合HTTP协议规范,同时保证方法注解中的占位符能和参数中注解中的对应的字段意义对应起来,能够拼接一个完成的URL请求,包括请求地址和请求参数。
接着分析parseMethodAnnotation(Annotation annotation)方法

    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(method = "DELETE", path = "remove/", hasBody = true)
        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({"X-Foo: Bar","X-Ping: Pong"})
        headers = parseHeaders(headersToParse);
      } else if (annotation instanceof Multipart) {
       //@Multipart注解不能重复使用
        if (isFormEncoded) {
          throw methodError(method, "Only one encoding annotation is allowed.");
        }
        isMultipart = true;
      } else if (annotation instanceof FormUrlEncoded) {
      //@FormUrlEncoded注解不能重复使用
        if (isMultipart) {
          throw methodError(method, "Only one encoding annotation is allowed.");
        }
        isFormEncoded = true;
      }
    }

可以看到对@DELETE@GET@HEAD@PATCH@POST@PUT@OPTIONS均是调用了parseHttpMethodAndPath方法,如下所示

   private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
     //只能有一个HTTP方法
      if (this.httpMethod != null) {
        throw methodError(method, "Only one HTTP method is allowed. Found: %s and %s.",
            this.httpMethod, httpMethod);
      }
      this.httpMethod = httpMethod;
      this.hasBody = hasBody;

      if (value.isEmpty()) {
        return;
      }

      // Get the relative URL path and existing query string, if present.
     // 针对形如 aaa/bbb?key1={key1}&key2={key2}的URL处理
      int question = value.indexOf('?');
      if (question != -1 && question < value.length() - 1) {
        // Ensure the query string does not have any named parameters.
       //确保查询串本能有命名参数
        String queryParams = value.substring(question + 1);
        Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
        if (queryParamMatcher.find()) {
          throw methodError(method, "URL query string \"%s\" must not have replace block. "
              + "For dynamic query parameters use @Query.", queryParams);
        }
      }

      this.relativeUrl = value;//相对地址
      this.relativeUrlParamNames = parsePathParameters(value);//通过正则表达式获取相对地址中{}包含的参数
    }

针对@Headers注解,则是parseHeaders方法,如下所示,比较简单,获取数组列表,然后对每一个元素用:拆分为两部分,前者为键,后者为值然后生成headers

    private Headers parseHeaders(String[] headers) {
      Headers.Builder builder = new Headers.Builder();
      for (String header : headers) {
        int colon = header.indexOf(':');
        if (colon == -1 || colon == 0 || colon == header.length() - 1) {
          throw methodError(method,
              "@Headers value must be in the form \"Name: Value\". Found: \"%s\"", header);
        }
        String headerName = header.substring(0, colon);
        String headerValue = header.substring(colon + 1).trim();
        if ("Content-Type".equalsIgnoreCase(headerName)) {
          try {
            contentType = MediaType.get(headerValue);
          } catch (IllegalArgumentException e) {
            throw methodError(method, e, "Malformed content type: %s", headerValue);
          }
        } else {
          builder.add(headerName, headerValue);
        }
      }
      return builder.build();
    }

接着分析
parseParameter( int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation)方法:

    
   private @Nullable ParameterHandler<?> parseParameter(
        int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) {
      ParameterHandler<?> result = null;
      if (annotations != null) {
        for (Annotation annotation : annotations) {
           //通过parseParameterAnnotation来获取对应的ParameterHandler
          ParameterHandler<?> annotationAction =
              parseParameterAnnotation(p, parameterType, annotations, annotation);

          if (annotationAction == null) {
            continue;
          }

          if (result != null) {
            throw parameterError(method, p,
                "Multiple Retrofit annotations found, only one allowed.");
          }

          result = annotationAction;
        }
      }

      if (result == null) {
         //当为最后一个参数的时候allowContinuation为true
        if (allowContinuation) {
          try {
              //Continuation.class是Kotlin协程模块中kotlin.coroutines.Continuation;
              //有关协程请参考https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html
            if (Utils.getRawType(parameterType) == Continuation.class) {
              isKotlinSuspendFunction = true;
              return null;
            }
          } catch (NoClassDefFoundError ignored) {
          }
        }
        throw parameterError(method, p, "No Retrofit annotation found.");
      }

      return result;
    }

实际上还是调用的是ParameterHandler<?> parseParameterAnnotation( int p, Type type, Annotation[] annotations, Annotation annotation)方法。由于这个方法比较长,但是做的事情还是很清楚的,就是根据api接口中申明的参数注解类型生成相应的ParameterHandler,同时参数不能为不可解析类型,就是前文的hasUnresolvableType(@Nullable Type type)的逻辑。未落不冲谈主题且限于篇幅,此处只是列出该方法的几个最外层的条件分支,根据不同的注解@Url,@Path,@Query,@QueryName,@QueryMap,@Header,@HeaderMap,@Feild,@FieldMap,@Part,@PartMap,@Body,@Tag,生成相应的ParameterHandler。

   private ParameterHandler<?> parseParameterAnnotation(
        int p, Type type, Annotation[] annotations, Annotation annotation) {
      if (annotation instanceof Url) { //如果是@Url注解,返回ParameterHandler.RelativeUrl   
         //省略一堆逻辑
         。。。
        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) {  //如果是@Path注解,返回ParameterHandler.Path        
       //省略一堆逻辑
         。。。
        Converter<?, String> converter = retrofit.stringConverter(type, annotations);
        return new ParameterHandler.Path<>(method, p, name, converter, path.encoded());

      } else if (annotation instanceof Query) { //如果是@Query注解,返回ParameterHandler.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);
          return new ParameterHandler.Query<>(name, converter, encoded).iterable();
        } else if (rawParameterType.isArray()) {
          Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
          Converter<?, String> converter =
              retrofit.stringConverter(arrayComponentType, annotations);
          return new ParameterHandler.Query<>(name, converter, encoded).array();
        } else {
          Converter<?, String> converter =
              retrofit.stringConverter(type, annotations);
          return new ParameterHandler.Query<>(name, converter, encoded);
        }

      } else if (annotation instanceof QueryName) {//如果是@QueryName 注解,返回ParameterHandler.QueryName  
        validateResolvableType(p, type);
        QueryName query = (QueryName) annotation;
        boolean encoded = query.encoded();

        Class<?> rawParameterType = Utils.getRawType(type);
        gotQueryName = 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);
          return new ParameterHandler.QueryName<>(converter, encoded).iterable();
        } else if (rawParameterType.isArray()) {
          Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
          Converter<?, String> converter =
              retrofit.stringConverter(arrayComponentType, annotations);
          return new ParameterHandler.QueryName<>(converter, encoded).array();
        } else {
          Converter<?, String> converter =
              retrofit.stringConverter(type, annotations);
          return new ParameterHandler.QueryName<>(converter, encoded);
        }

      } else if (annotation instanceof QueryMap) { //如果是@QueryMap 注解,返回ParameterHandler.QueryMap    
        //省略一堆逻辑
       。。。。
        return new ParameterHandler.QueryMap<>(method, p,
                valueConverter, ((QueryMap) annotation).encoded());

      } else if (annotation instanceof Header) { //如果是@Header 注解,返回ParameterHandler.Header  
        validateResolvableType(p, type);
        Header header = (Header) annotation;
        String name = header.value();

        Class<?> rawParameterType = Utils.getRawType(type);
        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);
          return new ParameterHandler.Header<>(name, converter).iterable();
        } else if (rawParameterType.isArray()) {
          Class<?> arrayComponentType = boxIfPrimitive(rawParameterType.getComponentType());
          Converter<?, String> converter =
              retrofit.stringConverter(arrayComponentType, annotations);
          return new ParameterHandler.Header<>(name, converter).array();
        } else {
          Converter<?, String> converter =
              retrofit.stringConverter(type, annotations);
          return new ParameterHandler.Header<>(name, converter);
        }

      } else if (annotation instanceof HeaderMap) {//如果是@HeaderMap 注解,返回ParameterHandler.Headers或者ParameterHandler.HeaderMap
        if (type == Headers.class) {
          return new ParameterHandler.Headers(method, p);//返回ParameterHandler.Headers   
        }

       //省略一堆逻辑
         。。。。

        return new ParameterHandler.HeaderMap<>(method, p, valueConverter); //返回ParameterHandler.HeaderMap

      } else if (annotation instanceof Field) {//如果是@Field 注解,返回ParameterHandler.Field
         //省略一堆逻辑
         。。。。
        Class<?> rawParameterType = Utils.getRawType(type);
        if (Iterable.class.isAssignableFrom(rawParameterType)) {
        //省略一堆逻辑
         。。。。
          return new ParameterHandler.Field<>(name, converter, encoded).iterable();
        } else if (rawParameterType.isArray()) {
           //省略一堆逻辑
         。。。。
          return new ParameterHandler.Field<>(name, converter, encoded).array();
        } else {
          //省略一堆逻辑
         。。。。
          return new ParameterHandler.Field<>(name, converter, encoded);
        }

      } else if (annotation instanceof FieldMap) { //如果是@FieldMap 注解,返回ParameterHandler.Field
         //省略一堆逻辑
         。。。。
        return new ParameterHandler.FieldMap<>(method, p,
                valueConverter, ((FieldMap) annotation).encoded());

      } else if (annotation instanceof Part) { //如果是@Part 注解,根据具体情况返回ParameterHandler.RawPart或者ParameterHandler.Part
        validateResolvableType(p, type);
        if (!isMultipart) {
          throw parameterError(method, p,
              "@Part parameters can only be used with multipart encoding.");
        }
        Part part = (Part) annotation;
        gotPart = true;

        String partName = part.value();
        Class<?> rawParameterType = Utils.getRawType(type);
        if (partName.isEmpty()) {
          if (Iterable.class.isAssignableFrom(rawParameterType)) {
            //省略一堆逻辑
            。。。
            return ParameterHandler.RawPart.INSTANCE.iterable();
          } else if (rawParameterType.isArray()) {
             //省略一堆逻辑
            。。。
            return ParameterHandler.RawPart.INSTANCE.array();
          } else if (MultipartBody.Part.class.isAssignableFrom(rawParameterType)) {
            return ParameterHandler.RawPart.INSTANCE;
          } else {
            throw parameterError(method, p,
                "@Part annotation must supply a name or use MultipartBody.Part parameter type.");
          }
        } else {
          Headers headers =
              Headers.of("Content-Disposition", "form-data; name=\"" + partName + "\"",
                  "Content-Transfer-Encoding", part.encoding());

          if (Iterable.class.isAssignableFrom(rawParameterType)) {
            //省略一堆逻辑
            。。。
            return new ParameterHandler.Part<>(method, p, headers, converter).iterable();
          } else if (rawParameterType.isArray()) {
             //省略一堆逻辑
            。。。
            return new ParameterHandler.Part<>(method, p, headers, converter).array();
          } else if (MultipartBody.Part.class.isAssignableFrom(rawParameterType)) {
            throw parameterError(method, p,
                "@Part parameters using the MultipartBody.Part must not "
                    + "include a part name in the annotation.");
          } else {
            Converter<?, RequestBody> converter =
                retrofit.requestBodyConverter(type, annotations, methodAnnotations);
            return new ParameterHandler.Part<>(method, p, headers, converter);
          }
        }

      } else if (annotation instanceof PartMap) {  //如果是@PartMap 注解,返回ParameterHandler.PartMap
      //省略一堆逻辑
       。。。。
        return new ParameterHandler.PartMap<>(method, p, valueConverter, partMap.encoding());

      } else if (annotation instanceof Body) {  //如果是@Body 注解,返回ParameterHandler.Body
        //省略一堆逻辑
       。。。。
        return new ParameterHandler.Body<>(method, p, converter);

      } else if (annotation instanceof Tag) { //如果是@Tag 注解,返回ParameterHandler.Tag
          //省略一堆逻辑
       。。。。

        return new ParameterHandler.Tag<>(tagType);
      }

      return null; // Not a Retrofit annotation.
    }

所有的根据注解生成具体的ParameterHandler都是继承自ParameterHandler,在生成真正的okhttp3.Request请求的时候是会调用复写ParameterHandler<T>apply(RequestBuilder builder, @Nullable T value)方法,以实现生成符合http规范的请求头,请求参数,请求体。后文会继续分析apply调用的时机。

回到前文ServiceMethod的parseAnnotations方法,如下所示,我们已经大体分析了 RequestFactoryparseAnnotations()方法,现在分析 HttpServiceMethodparseAnnotations()方法。

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

跟进HttpServiceMethodparseAnnotations(retrofit, method, requestFactory)去看一下

 static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
    boolean continuationWantsResponse = false;
    boolean continuationBodyNullable = false;

    Annotation[] annotations = method.getAnnotations();
    Type adapterType;
    if (isKotlinSuspendFunction) {//是否是Kotlin的suspend方法,因为我们定义在API接口GitHub里面的方法不是suspend,此处为false
      Type[] parameterTypes = method.getGenericParameterTypes();
      Type responseType = Utils.getParameterLowerBound(0,
          (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
      if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
        // Unwrap the actual body type from Response<T>.
        responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
        continuationWantsResponse = true;
      } else {
        // TODO figure out if type is nullable or not
        // Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
        // Find the entry for method
        // Determine if return type is nullable or not
      }

      adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
      annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
    } else {
      adapterType = method.getGenericReturnType();//方法的返回类型
    }
    //重点1,找到对应的callAdapter
    CallAdapter<ResponseT, ReturnT> 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<String>)");
    }
    // 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.");
    }
    //重点2,找到对应的Converter
    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);

    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    if (!isKotlinSuspendFunction) {
        //重点3,我们用到是CallAdapted
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
        //针对kotlin的非suspend方法
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } else {//针对kotlin的suspend方法
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
          continuationBodyNullable);
    }
  }
}

进入createCallAdapter方法看看逻辑

  private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
      Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
    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);
    }
  }

是调用的RetrofitcallAdapter方法,进去看一下,分析逻辑见注释。

  public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
      Annotation[] annotations) {
    checkNotNull(returnType, "returnType == null");
    checkNotNull(annotations, "annotations == null");
    //callAdapter传入的skipPast为null,因此callAdapterFactories.indexOf(skipPast)的值为-1,因此start为0
    int start = callAdapterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      //返回的是callAdapterFactories里面符合要要求的CallAdapter,前面的Retrofit的Builder在builder函数中
      //默认添加了[CompletableFutureCallAdapterFactory,DefaultCallAdapterFactory]或者[DefaultCallAdapterFactory]
      //如果用户不添加其他的CallAdapterFactory的话,我们在Github的API中返回值的类型是Call<List<Contributor>> ,returnType是Call.class类型的,
      //DefaultCallAdapterFactory恰好是针对Call.class,CompletableFutureCallAdapterFactory是针对CompletableFuture.class,
      //因此拿到的是DefaultCallAdapterFactory,返回的是DefaultCallAdapterFactory,生成的
      CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
      if (adapter != null) {
        return adapter;
      }
    }

    StringBuilder builder = new StringBuilder("Could not locate call adapter for ")
        .append(returnType)
        .append(".\n");
    if (skipPast != null) {
      builder.append("  Skipped:");
      for (int i = 0; i < start; i++) {
        builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
      }
      builder.append('\n');
    }
    builder.append("  Tried:");
    for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
      builder.append("\n   * ").append(callAdapterFactories.get(i).getClass().getName());
    }
    throw new IllegalArgumentException(builder.toString());
  }

通过上面分析可以知道,得到的是DefaultCallAdapterFactory通过get( Type returnType, Annotation[] annotations, Retrofit retrofit)方法拿到的CallAdapter,我们进入看一下

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

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

  @Override public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    if (!(returnType instanceof ParameterizedType)) {
      throw new IllegalArgumentException(
          "Call return type must be parameterized as Call<Foo> or Call<? extends Foo>");
    }
  //返回形如Call<Foo>或者 Call<? extends Foo>中Foo的类型
    final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);

    final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
        ? null
        : callbackExecutor;
    //此处创建了一个CallAdapter
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call<Object> adapt(Call<Object> call) {
          //如果传入了executor则返回一ExecutorCallbackCall,让call在executor环境中执行
        return executor == null
            ? call
            : new ExecutorCallbackCall<>(executor, call);
      }
    };
  }
  //省略其他代码
  。。。。。。。
}

说明返回的是一个匿名的CallAdapter,adapt方法如果没有传入新的线程执行环境executor 则返回原来的call,否则返回在传入的executor 中执行的call。
接着跟进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);
    }
  }

跟进去进一步分析

  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");
    //传入的是里面的callAdapter.responseType()
    //因为传入的skipPast为null.onverterFactories.indexOf(skipPast)为-1,因此start为0
    int start = converterFactories.indexOf(skipPast) + 1;
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      //逻辑和nextCallAdapter类似
      //返回的是converterFactories里面符合要要求的Converter,前面的Retrofit的Builder在builder函数中
      //默认添加了[BuiltInConverters,自定义converts集合,OptionalConverterFactory]或者[BuiltInConverters,自定义converts集合]
      //如果因为我们添加了GsonConverterFactory了,是因为我们在Github的API中返回值的类型是Call<List<Contributor>> ,Type是List<Contributor>类型的,
      //BuiltInConverters的responseBodyConverter只处理ResponseBody.class,不符合要求
      //OptionalConverterFactory则是只处理Optional.class类型,也不符合要求
      //而我们配置GsonConverterFactory在responseBodyConverter方法里面针对任意类型做适配,返回GsonResponseBodyConverter,符合要求
      Converter<ResponseBody, ?> converter =
          converterFactories.get(i).responseBodyConverter(type, annotations, this);
      if (converter != null) {
        //noinspection unchecked
        return (Converter<ResponseBody, T>) converter;
      }
    }

    StringBuilder builder = new StringBuilder("Could not locate ResponseBody converter for ")
        .append(type)
        .append(".\n");
    if (skipPast != null) {
      builder.append("  Skipped:");
      for (int i = 0; i < start; i++) {
        builder.append("\n   * ").append(converterFactories.get(i).getClass().getName());
      }
      builder.append('\n');
    }
    builder.append("  Tried:");
    for (int i = start, count = converterFactories.size(); i < count; i++) {
      builder.append("\n   * ").append(converterFactories.get(i).getClass().getName());
    }
    throw new IllegalArgumentException(builder.toString());
  }

在拿到Converter后我们再次回到方法 static <ResponseT, ReturnT>HttpServiceMethod<ResponseT, ReturnT> parseAnnotations( Retrofit retrofit, Method method, RequestFactory requestFactory)可以看到返回的是CallAdapted。显然CallAdaptedHttpServiceMethod的子类

 static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
 //省略一堆逻辑
 CallAdapter<ResponseT, ReturnT> callAdapter =
        createCallAdapter(retrofit, method, adapterType, annotations);
 Type responseType = callAdapter.responseType();
    //省略一堆逻辑
    Converter<ResponseBody, ResponseT> 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<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
          continuationBodyNullable);
    }
  }

前面我们提到创建代理对象后我们调用定义的API的某个非继承自object的方法的时候实际上是调用的ServiceMethodinvoke方法,而ServiceMethodinvoke方法是抽象方法,它的实现是在子类HttpServiceMethod中,如下所示

abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
 
。。。 省略其他代码
  @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);
。。。 省略其他代码
}

可以看到在invoke方法中创建了OkHttpCall然后调用adapt方法而adapt也是抽象方法,实际上是在子类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) {
    //调用的是传入的callAdapter的adapt方法
      return callAdapter.adapt(call);
    }
  }

从前面的代码我们知道传入的callAdapter实际上是在DefaultCallAdapterFactoryget方法中创建的,adapt方法返回的就是原来的call.回到最开始,也就是说创建的call 最终并未网络请求,在call.execute()的时候才会返回数据

  // Create a call instance for looking up Retrofit contributors.
        Call<List<Contributor>> call = github.contributors("square", "retrofit");
        // Fetch and print a list of the contributors to the library.
        List<Contributor> contributors = call.execute().body();

此时的call实际上是OkHttpCall,我们进入OkHttpCallexcute方法

final class OkHttpCall<T> implements Call<T> {
  @GuardedBy("this")
  private @Nullable okhttp3.Call rawCall;
  @GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
  private @Nullable Throwable creationFailure;
  @GuardedBy("this")
  private boolean executed;
  
  
 @Override public Response<T> execute() throws IOException {
    okhttp3.Call call;

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

      if (creationFailure != null) {
        if (creationFailure instanceof IOException) {
          throw (IOException) creationFailure;
        } else if (creationFailure instanceof RuntimeException) {
          throw (RuntimeException) creationFailure;
        } else {
          throw (Error) creationFailure;
        }
      }

      call = rawCall;
      //一开始rawCall为null,必然会调用createRawCall()
      if (call == null) {
        try {
          call = rawCall = createRawCall();
        } catch (IOException | RuntimeException | Error e) {
          throwIfFatal(e); //  Do not assign a fatal error to creationFailure.
          creationFailure = e;
          throw e;
        }
      }
    }

    if (canceled) {
      call.cancel();
    }
   //执行的是createRawCall生成的call的execute()方法
    return parseResponse(call.execute());
  }
  
   private okhttp3.Call createRawCall() throws IOException {
    //callFactory为OkHttpClient
    //requestFactory为调用ServiceMethod.parseAnnotations(Retrofit retrofit, Method method)方法体里面
    //RequestFactory.parseAnnotations(retrofit, method);返回的值
    okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }
}

上面的createRawCall()方法实际上是通过OkHttpClient的newCall方法返回RealCall,如下所示,执行的是RealCallexcute方法,RealCallexcute的逻辑会在后期的OkHttp源码分析里面进一步说明

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

在调用createRawCall方法的时候调用了RequestFactorycreate(Object[] args)方法来生成相应的请求,而RequestFactory 在前面解析API接口方法注解和方法参数注解的时候就已经生成了。

 okhttp3.Request create(Object[] args) throws IOException {
    @SuppressWarnings("unchecked") // It is an error to invoke a method with the wrong arg types.
    ParameterHandler<Object>[] handlers = (ParameterHandler<Object>[]) parameterHandlers;

    int argumentCount = args.length;
    if (argumentCount != handlers.length) {
      throw new IllegalArgumentException("Argument count (" + argumentCount
          + ") doesn't match expected count (" + handlers.length + ")");
    }
    //Retrofit初始化的时候传入的baseUrl,方法解析的时候获取到的请求类型,
    //相对路径,请求头,请求内容的类型,是否带有方法体是否编码等
    RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl,
        headers, contentType, hasBody, isFormEncoded, isMultipart);
    //针对kotlin的suspend方法处理
    if (isKotlinSuspendFunction) {
      // The Continuation is the last parameter and the handlers array contains null at that index.
      argumentCount--;
    }

    List<Object> argumentList = new ArrayList<>(argumentCount);
    for (int p = 0; p < argumentCount; p++) {
      argumentList.add(args[p]);
      //重点,前面在解析方法参数注解的时候生成了很多ParameterHandler,通过ParameterHandler的apply
      //方法将这些注解关联的内容配置到RequestBuilder里面
      //例如是@Head则调用RequestBuilder.addHeader(String name, String value)
      //是@Path则调用RequestBuilder.addPathParam(String name, String value, boolean encoded) 
      handlers[p].apply(requestBuilder, args[p]);
    }
    //RequestBuilder.get()方法返回的的是Request.Builder 类型,跟RequestBuilder不是一个类型
    //可以理解为RequestBuilder的get()方法相当于一个build()方法,只不过生成不是Request类型
    //而是Request.Builder类型,而Request.Builder的build()方法返回的才是Request
    return requestBuilder.get()
        .tag(Invocation.class, new Invocation(method, argumentList))
        .build();
  }

再看一下OkHttpCallResponse<T> parseResponse(okhttp3.Response rawResponse)方法:

  Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    // Remove the body's source (the only stateful object) so we can pass the response along.
    rawResponse = rawResponse.newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

    int code = rawResponse.code();
    //小于200表示服务器收到请求,需要请求者继续执行操作
    //300~399重定向,需要进一步的操作以完成请求
    //400~499客户端错误,请求包含语法错误或无法完成请求
    //500~599服务器错误,服务器在处理请求的过程中发生了错误
    //参考https://www.runoob.com/http/http-status-codes.html

    if (code < 200 || code >= 300) {
      try {
        // Buffer the entire body to avoid future I/O.
        ResponseBody bufferedBody = Utils.buffer(rawBody);
        return Response.error(bufferedBody, rawResponse);
      } finally {
        rawBody.close();
      }
    }
    //204表示无内容。服务器成功处理,但未返回内容。在未更新网页的情况下,可确保浏览器继续显示当前文档
    //205表示重置内容。服务器处理成功,用户终端(例如:浏览器)应重置文档视图。可通过此返回码清除浏览器的表单域
    if (code == 204 || code == 205) {
      rawBody.close();
      return Response.success(null, rawResponse);
    }

    ExceptionCatchingResponseBody catchingBody = new ExceptionCatchingResponseBody(rawBody);
    try {
      //前面分析得到的responseConverter是GsonResponseBodyConverter,将ExceptionCatchingResponseBody
      //反序列化成实体类
      T body = responseConverter.convert(catchingBody);
      //用retrofit2.Response类型来包装okhttp3.Response,retrofit2.Response的body()会返回相应的实体类T
      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;
    }
  }

因为前面Clall的excute()方法返回的是Response<T>,因此需要继续调用Responsebody()返回具体类型T.

总结

Retrofitcreate方法调用的时候通过动态代理生成代理对象,当调用方法的时候又会去根据接口中方法的注解,参数的注解,返回值的类型选择对应的RequestBodyConverter,ResponseBodyConverter,CallAdapter,并生成ServerMethod并缓存起来,这样下次就不用再去解析。然后调用ServerMethod的invoke方法,又会调用子类的adapt方法,实际上会调用CallAdapter的adapt方法,adapt方法会生成相应的Call转换成另一种类型,默认不做转换和还是原来的Call类型,执行Call的同步方法excute()或者异步部方法enqueue方后会根据解析API接口定义中的参数和方法的注解来配置请求头,方法名,参数,请求体等信息,生成一个OkHttp的RealCall来进行真正的网络请求,返回的结果根据接口定义中的返回类型选择相应的ResponseBodyConverter做转换。
值得注意的是,Retrofit中对泛型的处理也是值得学习的
最后来一张时序图

时序图.png

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