Retrofit源码解析

2 分钟 阅读

Retrofit是一个基于OKHttp的网络请求框架,具有高解耦,支持RxJava和RxAndroid,支持多种Json解析框架,代码风格使用注解方式,简洁易懂等诸多优点。

Retrofit的使用在这里就不赘述了,网上有很多教程。

1.Retrofit类

Retrofit的创建使用了构造者模式,我们从他的构造者来开始分析。

public static final class Builder {
    private final Platform platform;//可以获取平台信息的类
    private @Nullable okhttp3.Call.Factory callFactory;
    private HttpUrl baseUrl;
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    private final List<CallAdapter.Factory> adapterFactories = new ArrayList<>();
    private @Nullable Executor callbackExecutor;
    private boolean validateEagerly;

    Builder(Platform platform) {
      this.platform = platform;
      // 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());
    }

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

    Builder(Retrofit retrofit) {
      platform = Platform.get();
      callFactory = retrofit.callFactory;
      baseUrl = retrofit.baseUrl;
      converterFactories.addAll(retrofit.converterFactories);
      adapterFactories.addAll(retrofit.adapterFactories);
      // Remove the default, platform-aware call adapter added by build().
      adapterFactories.remove(adapterFactories.size() - 1);
      callbackExecutor = retrofit.callbackExecutor;
      validateEagerly = retrofit.validateEagerly;
    }
    
    public Builder client(OkHttpClient client) {
      return callFactory(checkNotNull(client, "client == null"));
    }

    public Builder callFactory(okhttp3.Call.Factory factory) {
      this.callFactory = checkNotNull(factory, "factory == null");
      return this;
    }
    /**
    * 设置baseUrl
    */
    public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      HttpUrl httpUrl = HttpUrl.parse(baseUrl);
      if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
      }
      return baseUrl(httpUrl);
    }

    public Builder baseUrl(HttpUrl baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      List<String> pathSegments = baseUrl.pathSegments();
      if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
        throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
      }
      this.baseUrl = baseUrl;
      return this;
    }
    /**
    * 添加解析工具,支持Gson、Jackson、Moshi、Protobuf、Wire、Simple XML、Scalars.当然,你也可以自定义一个Converter.Factory类。
    */
    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

    /**
    * 适配器,默认为Call,可以使用RxJava的Observable
    */
    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      adapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

    public Builder callbackExecutor(Executor executor) {
      this.callbackExecutor = checkNotNull(executor, "executor == null");
      return this;
    }

    public Builder validateEagerly(boolean validateEagerly) {
      this.validateEagerly = validateEagerly;
      return this;
    }

    public Retrofit build() {
      if (baseUrl == null) {//baseUrl必须设置
        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) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy(备份) of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

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

接下来看一下create方法,他的作用是为我们构建接口的实例。在该方法内,拿到了所有的参数,注解信息然后就可以去构造RequestBody,再去构建Request,得到Call对象封装后返回。此处使用了动态代理。

public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);//判断service是否为接口类,以及该接口是否有继承
    if (validateEagerly) {//是否验证接口类中的所有方法
      eagerlyValidateMethods(service);//(1)
    }
    //动态代理
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.//getDeclaringClass()获取方法所在的类
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);//调用方法
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            //获得缓存中的ServiceMethod对象
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            //根据参数新建OkHttpCall对象
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            //
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }

(1)eagerlyValidateMethods(Class<?> service)方法

/**
* 验证所用是否为默认定义的方法?
*/
private void eagerlyValidateMethods(Class<?> service) {
    Platform platform = Platform.get();
    for (Method method : service.getDeclaredMethods()) {
      if (!platform.isDefaultMethod(method)) {//此处的platform.isDefaultMethod(method)永远为false
        loadServiceMethod(method);//(2)获取缓存中的Method对象
      }
    }
  }

(2)loadServiceMethod(Method method)方法

/**
* 获取缓存中的Method对象
*/
ServiceMethod<?, ?> loadServiceMethod(Method method) {
    //serviceMethodCache是ConcurrentHashMap对象
    ServiceMethod<?, ?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = new ServiceMethod.Builder<>(this, method).build();
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }