Retrofit原理分析

1,323 阅读6分钟

创建Retrofi对象

构造Retrofit.Builder对象时默认会传入Platfrom对象

Retrofit.java
public Builder() {
  this(Platform.get());
}

在Android中使用Retrofit,传入Android对象

Platform.java
private static final Platform PLATFORM = findPlatform();

static Platform get() {
  return PLATFORM;
}

private static Platform findPlatform() {
  try {
    Class.forName("android.os.Build");
    if (Build.VERSION.SDK_INT != 0) {
      return new Android();
    }
  } catch (ClassNotFoundException ignored) {
  }
  return new Platform(true);
}

构建Retrofit对象时默认添加了许多属性OkHttpClient,Executor,CallAdapter,Converter

Retrofit.java
public Retrofit build() {
  if (baseUrl == null) {
    throw new IllegalStateException("Base URL required.");
  }
  okhttp3.Call.Factory callFactory = this.callFactory;
  if (callFactory == null) {
    callFactory = new OkHttpClient();
  }
  // 回调执行器时,handler回调主线程执行
  Executor callbackExecutor = this.callbackExecutor;
  if (callbackExecutor == null) {
    callbackExecutor = platform.defaultCallbackExecutor();
  }

  // 复制默认Call adapter.
  List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
  callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

  List<Converter.Factory> converterFactories = new ArrayList<>(
    1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
  // 添加 converter
  converterFactories.add(new BuiltInConverters());
  converterFactories.addAll(this.converterFactories);
  converterFactories.addAll(platform.defaultConverterFactories());
  // validateEagerly为true,提前生成动态代理的方法
  return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
  unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}

创建网络请求代理对象

创建接口的代理对象

Retrofit.java
public <T> T create(final Class<T> service) {
  // service为接口,service没有泛型和service实现的接口没有泛型
  validateServiceInterface(service);
  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
  new InvocationHandler() {
    private final Platform platform = Platform.get();
    private final Object[] emptyArgs = new Object[0];
    // 代理对象调用的方法
    @Override public @Nullable Object invoke(Object proxy, Method method,
    @Nullable Object[] args) throws Throwable {
      // Object方法正常调用
      if (method.getDeclaringClass() == Object.class) {
        return method.invoke(this, args);
      }
      // Default方法正常调用
      if (platform.isDefaultMethod(method)) {
        return platform.invokeDefaultMethod(method, service, proxy, args);
      }
    // Java返回OkHttpCall对象,Android返回ExecutorCallbackCall对象
    return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
  }
  });
}

生成retrofit.Call对象

先从缓存中获取ServiceMethod,缓存中没有创建ServiceMethod并放在缓存中。

ServiceMethod.java
ServiceMethod<?> loadServiceMethod(Method method) {
  // 代理方法缓存
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;
  synchronized (serviceMethodCache) {
    result = serviceMethodCache.get(method);
    if (result == null) {
      // 创建构造方法
      result = ServiceMethod.parseAnnotations(this, method);
      serviceMethodCache.put(method, result);
    }
  }
  return result;
}

获取ServiceMothed对象过程,解析方法的注解和参数创建RequestFactory对象

ServiceMethod.java
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
  // 获取方法注解,构造请求参数
  RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
  ···
  // 默认返回CallAdapted对象
  return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}

构造RequestFactory对象

RequestFactory.java
RequestFactory build() {
  ···
  // 解析方法参数和注解
  return new RequestFactory(this);
}

通过Retrofit对象获取CallAdapter,Converter和okhttp.call.factory对象,并通过这些对象构造CallAdapted对象.

HttpServiceMethod.java
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
  ···
  // 获取ResponseConverter,在Retrofit初始化时配置
  Converter<ResponseBody, ResponseT> responseConverter =
  createResponseConverter(retrofit, method, responseType);
  okhttp3.Call.Factory callFactory = retrofit.callFactory;
  if (!isKotlinSuspendFunction) {
    // 不使用kotlin协程
    return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
  }
  ···
}

CallAdapted继承HttpServiceMethod

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;
  }
  // Adaptrt主要方法
  @Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
    return callAdapter.adapt(call);
  }
}

Android默认CallAdapterFactory,get方法生成CallAdapter对象。

ServiceMethod对象的invoke方法最终调用CallAdapter对象的adapt方法,返回ExecutorCallbackCall对象,ExecutorCallbackCall是retrofit.call的子类,包含Executor对象和OkHttpCall对象。

DefaultCallAdapterFactory.java
@Override public @Nullable CallAdapter<?, ?> get(

  ···
  // 获取执行器
  final Executor executor = Utils.isAnnotationPresent(annotations, SkipCallbackExecutor.class)
    ? null
  : callbackExecutor;

  return new CallAdapter<Object, Call<?>>() {
    @Override public Type responseType() {
      return responseType;
    }
    // 返回ExecutorCallbackCall对象
    @Override public Call<Object> adapt(Call<Object> call) {
      return executor == null
      ? call
      : new ExecutorCallbackCall<>(executor, call);
    }
  };
}

执行网络请求

ExecutorCallbackCall委托OkHttpCall发送网络请求,然后将结果通过Executor回调到主线程

ExecutorCallbackCall异步HTTP请求

ExecutorCallbackCall.java
@Override public void enqueue(final Callback<T> callback) {

  delegate.enqueue(new Callback<T>() {
    @Override public void onResponse(Call<T> call, final Response<T> response) {
      // 回调主线程
      callbackExecutor.execute(() -> {
      if (delegate.isCanceled()) {
        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(() -> callback.onFailure(ExecutorCallbackCall.this, t));
    }
  });
}

Executor通过Handler回调主线程

static class MainThreadExecutor implements Executor {
  private final Handler handler = new Handler(Looper.getMainLooper());

  @Override public void execute(Runnable r) {
    handler.post(r);
  }
}

ExecutorCallbackCall同步HTTP请求

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

OkHttpCall是对OkHttpClient的包装,OKHttpCall的成员变量包括:RequestFactory,方法参数,OkHttpClient,Converter,网络请求最终是由OkHttpClient创建的okhttp.Call对象发出的。

OkHttpCall异步HTTP请求

OkHttpCall.java
@Override public void enqueue(final Callback<T> callback) {
  Objects.requireNonNull(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 {
        // 创建RealCall,包括创建Request
        call = rawCall = createRawCall();
      } catch (Throwable t) {
        throwIfFatal(t);
        failure = creationFailure = t;
      }
    }
  }
  if (failure != null) {
    // 失败回调
    callback.onFailure(this, failure);
    return;
  }
  if (canceled) {
    // 取消请求
    call.cancel();
  }
  call.enqueue(new okhttp3.Callback() {
    @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
      Response<T> response;
      try {
        // 将Json或Xml等转换为对象
        response = parseResponse(rawResponse);
      } catch (Throwable e) {
        throwIfFatal(e);
        callFailure(e);
        return;
      }
      try {
        callback.onResponse(OkHttpCall.this, response);
      } catch (Throwable t) {
        throwIfFatal(t);
        t.printStackTrace(); 
      }
    }
    @Override public void onFailure(okhttp3.Call call, IOException e) {
      callFailure(e);
    }
    private void callFailure(Throwable e) {
      try {
        callback.onFailure(OkHttpCall.this, e);
      } catch (Throwable t) {
        throwIfFatal(t);
        t.printStackTrace(); 
      }
    }
  });
}

OkHttpCall同步HTTP请求

OkHttpCall.java
@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;
    if (call == null) {
      try {
        // 创建RealCall对象,包括创建Request
        call = rawCall = createRawCall();
      } catch (IOException | RuntimeException | Error e) {
        throwIfFatal(e); 
        creationFailure = e;
        throw e;
      }
    }
  }
  if (canceled) {
    call.cancel();
  }
  // 将Json或Xml等转换为对象
  return parseResponse(call.execute());
}

通过RequestFactory创建request对象

RequestFactory.java
okhttp3.Request create(Object[] args) throws IOException {
  @SuppressWarnings("unchecked") 
  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 + ")");
  }

  RequestBuilder requestBuilder = new RequestBuilder(httpMethod, baseUrl, relativeUrl,
    headers, contentType, hasBody, isFormEncoded, isMultipart);

  if (isKotlinSuspendFunction) {
    // Continuation是最后一个参数,并且handlers数组在该索引处包含null。
    argumentCount--;
  }

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

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

通过Converter转化RequestBody,ResponseBody

Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
  ResponseBody rawBody = rawResponse.body();
  ···
  //请求是否成功 
  try {
    // 调用responseConverter转化Body
    T body = responseConverter.convert(catchingBody);
    return Response.success(body, rawResponse);
  } catch (RuntimeException e) {
    catchingBody.throwIfCaught();
    throw e;
  }
}

默认Converter,根据策略选择

final class BuiltInConverters extends Converter.Factory {
  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    if (type == ResponseBody.class) {
      if (Utils.isAnnotationPresent(annotations, Streaming.class)) {
        return StreamingResponseBodyConverter.INSTANCE;
      }
      return BufferingResponseBodyConverter.INSTANCE;
    }
    if (type == Void.class) {
      return VoidResponseBodyConverter.INSTANCE;
    }
    return null;
  }

  @Override
  public Converter<?, RequestBody> requestBodyConverter(Type type,
      Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    if (RequestBody.class.isAssignableFrom(Utils.getRawType(type))) {
      return RequestBodyConverter.INSTANCE;
    }
    return null;
  }

  @Override public Converter<?, String> stringConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    if (type == String.class) {
      return StringConverter.INSTANCE;
    }
    return null;
  }

  static final class StringConverter implements Converter<String, String> {
    static final StringConverter INSTANCE = new StringConverter();

    @Override public String convert(String value) throws IOException {
      return value;
    }
  }

  static final class VoidResponseBodyConverter implements Converter<ResponseBody, Void> {
    static final VoidResponseBodyConverter INSTANCE = new VoidResponseBodyConverter();

    @Override public Void convert(ResponseBody value) throws IOException {
      value.close();
      return null;
    }
  }

  static final class RequestBodyConverter implements Converter<RequestBody, RequestBody> {
    static final RequestBodyConverter INSTANCE = new RequestBodyConverter();

    @Override public RequestBody convert(RequestBody value) throws IOException {
      return value;
    }
  }

  static final class StreamingResponseBodyConverter
      implements Converter<ResponseBody, ResponseBody> {
    static final StreamingResponseBodyConverter INSTANCE = new StreamingResponseBodyConverter();

    @Override public ResponseBody convert(ResponseBody value) throws IOException {
      return value;
    }
  }

  static final class BufferingResponseBodyConverter
      implements Converter<ResponseBody, ResponseBody> {
    static final BufferingResponseBodyConverter INSTANCE = new BufferingResponseBodyConverter();

    @Override public ResponseBody convert(ResponseBody value) throws IOException {
      try {
        // Buffer the entire body to avoid future I/O.
        return Utils.buffer(value);
      } finally {
        value.close();
      }
    }
  }

  static final class ToStringConverter implements Converter<Object, String> {
    static final ToStringConverter INSTANCE = new ToStringConverter();

    @Override public String convert(Object value) {
      return value.toString();
    }
  }
}

ResponseBody转对象

GsonResponseBodyConverter.java
@Override public T convert(ResponseBody value) throws IOException {
  JsonReader jsonReader = gson.newJsonReader(value.charStream());
  try {
    T result = adapter.read(jsonReader);
    if (jsonReader.peek() != JsonToken.END_DOCUMENT) {
      throw new JsonIOException("JSON document was not fully consumed.");
    }
    return result;
  } finally {
    value.close();
  }
}

对象转RequestBody

GsonRequestBodyConverter.java
@Override public RequestBody convert(T value) throws IOException {
  Buffer buffer = new Buffer();
  Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
  JsonWriter jsonWriter = gson.newJsonWriter(writer);
  adapter.write(jsonWriter, value);
  jsonWriter.close();
  return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
}

总结

设计模式:构建者模式,工厂模式,代理模式,外观模式

Retrofit是在运行时生成代理对象,代理对象的代理方法会缓存在内存中,优化程序执行的时间。

Retrofit类分工

  1. 网络请求需要一个网络访问的对象,Retrofit使用OkHttp并自己定义了retrofit.Call
  2. 针对易变的url和请求方式,Retrofit使用了方法注解的方式,可读性良好,扩展性优异,但这需要实现对接口函数中注解的解析,这样就有了ServiceMethod。
  3. 针对Http请求的各种设置,Retrofit使用的OkHttp有拦截器机制。
  4. 针对返回的数据类型,Retrofit无法提供一个万能的转换类,所以Retrofit提供了扩展接口,允许开发者自己定义ConverterFactory和Converter,去实现潜在的数据类型转换。
  5. Retrofit像一个工厂一样生产Call网络请求对象。
    Retrofit执行过程