retrofit原理详解

前言

  Retrofit retrofit = new Retrofit.Builder()
                              .baseUrl("http://www.jianshu.com/")
                              //设置转换工厂
                              .addConverterFactory(GsonConverterFactory.create())
                              //设置适配器
                              .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                              .build();

这里之所以叫Retrofit客户端。客户端提供的子系统有:
1.serviceMethodCache(自定义的接口映射对象集合)
2.baseUrl(请求地址)
3.callFactory(默认为OkHttpCall)
4.converterFactories(数据解析器工厂集合)
5.callAdapterFactories(Call适配器工厂集合)
6.callbackExecutor(回调执行,android平台默认为MainThreadExecutor)

关于Retrofit客户端的创建

客户端的创建有两种方式:
第一种就是使用构造函数,如下所示。
第二种就是Retrofit.Builder()。
我们一般使用第二种方式来创建客户端。

public final class Retrofit {
  //对网络请求接口中方法注解进行解析后得到的对象,缓存到map中
  private final Map> serviceMethodCache = new ConcurrentHashMap<>();
  //网络请求器工厂
  final okhttp3.Call.Factory callFactory;
  //网络请求适配器器工厂集合
  final List callAdapterFactories;
  //数据转换器工厂集合
   final List converterFactories;
  //回调方法执行器
  final @Nullable Executor callbackExecutor;

  Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List converterFactories, List callAdapterFactories,
      @Nullable Executor callbackExecutor, boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
    this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }
}

接下来看看通过构建者模式创造的Retrofit客户端,使用构建者模式,有如下好处,对外可以屏蔽创建对象的细节,同时也可以自由配置Retrofit客户端的属性。

 public static final class Builder {
    private final Platform platform;
    private @Nullable okhttp3.Call.Factory callFactory;
    private @Nullable HttpUrl baseUrl;
    private final List converterFactories = new ArrayList<>();
    private final List callAdapterFactories = new ArrayList<>();
    private @Nullable Executor callbackExecutor;
    private boolean validateEagerly;
  
  public Builder() {
      this(Platform.get());
    }
  

接着就到Platform.get()方法里

class Platform {
  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) {
        //安卓平台的platform
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    try {
      Class.forName("java.util.Optional");
      return new Java8();
    } catch (ClassNotFoundException ignored) {
    }
    return new Platform();
  }

接着看看这个安卓平台的做了啥事

static class Android extends Platform {
    @IgnoreJRERequirement // Guarded by API check.
    @Override boolean isDefaultMethod(Method method) {
      if (Build.VERSION.SDK_INT < 24) {
        return false;
      }
      return method.isDefault();
    }

    @Override public Executor defaultCallbackExecutor() {
      //返回一个默认的回调方法执行器,子线程请求后的数据通过这个来返回到主线程
      return new MainThreadExecutor();
    }
  
  //默认的网络请求适配器工厂是ExecutorCallAdapterFactory ,常用的还有
  //RxjavaCallAdapter,callAdapterFactory
    @Override List 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);
    }

    @Override int defaultCallAdapterFactoriesSize() {
      return Build.VERSION.SDK_INT >= 24 ? 2 : 1;
    }
    
  //默认的转换器,常用的有GsonConverterFactory
    @Override List defaultConverterFactories() {
      return Build.VERSION.SDK_INT >= 24
          ? singletonList(OptionalConverterFactory.INSTANCE)
          : Collections.emptyList();
    }

    @Override int defaultConverterFactoriesSize() {
      return Build.VERSION.SDK_INT >= 24 ? 1 : 0;
    }

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

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

可以看出这个Build类初始化了如下:
Platform:安卓平台对象 网络请求适配器工厂:CallAdapterFactory
数据转换器工厂:converterFactory 回调执行器:callbackExecutor

初始化数据转换器

addConverterFactory(GsonConverterFactory.creat())

先看看GsonConverterFactory.creat()里做了啥事

public final class GsonConverterFactory extends Converter.Factory {

     public static GsonConverterFactory create() {
    return create(new Gson());
  }

    public static GsonConverterFactory create(Gson gson) {
    if (gson == null) throw new NullPointerException("gson == null");
    return new GsonConverterFactory(gson);
  }

    private GsonConverterFactory(Gson gson) {
    this.gson = gson;
  }
  
  //在自定义数据转化器时需重写这两个方法
     @Override
  public Converter responseBodyConverter(Type type, Annotation[] annotations,
      Retrofit retrofit) {
    TypeAdapter adapter = gson.getAdapter(TypeToken.get(type));
    return new GsonResponseBodyConverter<>(gson, adapter);
  }

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

这就是创建了一个还有Gson对象的GsonConverterFactory,并添加进converterFactorues中

 public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

由此看出
1.Retrofit默认使用Gson进行解析
2.若使用其他解析方式(如XML或Protocobuf),也可通过自定义数据解析器来实现(必须继承 Converter.Factory),重写那两个方法。

还有最后一个步骤,build(),Retrofit客户端就创建完成了。

 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) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // 配置网络请求适配器工厂
      List callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

      // 配置数据转换器工厂
      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);
    }
  }

创建网络请求接口的实例

    public interface Service{
      @GET("wanandroid")
      Call getCall();
}

  //使用了外观模式,通过传入class可以对每一个网络请求接口的访问
  Service service = retrofit.create(Service.class);

  Call call = service.getCall();

Retrofit是通过动态代理模式创建网络接口的实例,同时,通过解析注解("wanandroid")进行了网络请求参数的配置

现在先来看接口的实例如何创建出来的

 public  T create(final Class service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class[] { service },
        new InvocationHandler() {
          //这就是配置了那个数据转换器和网络适配器和回调池的platform
          private final Platform platform = Platform.get();
          private final Object[] emptyArgs = new Object[0];

          @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.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }

接着看loadServiceMethod()里做了啥事

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

接着去看parseAnnotations里做了啥事

  static  ServiceMethod parseAnnotations(Retrofit retrofit, Method method) {
    //这个就是去解析一些请求参数,比如说是否有请求体,请求方法是get post等等
    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.");
    }
  //这里就是去解析注解信息带参数path的
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

最后就生成了一个serviceMethod对象。

接下来去分析一下这个serviceMethod

final class HttpServiceMethod extends ServiceMethod {
  //解析参数
  static  HttpServiceMethod parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
    CallAdapter callAdapter = createCallAdapter(retrofit, method);
    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 responseConverter =
        createResponseConverter(retrofit, method, responseType);

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

      //去遍历网络请求适配工厂
  // //网络接口方法的返回值类型来确定合适的CallAdapter实例
  private static  CallAdapter createCallAdapter(
      Retrofit retrofit, Method method) {
    Type returnType = method.getGenericReturnType();
    Annotation[] annotations = method.getAnnotations();
    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);
    }
  }

  //去遍历数据转换器工厂
  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);
    }
  }

  private final RequestFactory requestFactory;
  private final okhttp3.Call.Factory callFactory;
  private final CallAdapter callAdapter;
  private final Converter responseConverter;

  private HttpServiceMethod(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
      CallAdapter callAdapter,
      Converter responseConverter) {
    this.requestFactory = requestFactory;
    this.callFactory = callFactory;
    this.callAdapter = callAdapter;
    this.responseConverter = responseConverter;
  }
  
//重点在这,生成serviceMethod对象时,会调用到invoke方法
  @Override ReturnT invoke(Object[] args) {
    return callAdapter.adapt(
        new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
  }
}

我们知道,Retrofit是对OkHttp做了一层封装,具体的网络发起人还是OkHttp,关键是怎么样通过这个serviceMethod来完成的呢?
先来看看构造函数,接收四个,第一个就是请求工厂,包含所有的请求参数,第二个就是网络接口的参数,第三个就是网络接口转换工厂,第四个就是数据转化工厂。

 OkHttpCall(RequestFactory requestFactory, Object[] args,
      okhttp3.Call.Factory callFactory, Converter responseConverter) {
    this.requestFactory = requestFactory;
    this.args = args;
    this.callFactory = callFactory;
    this.responseConverter = responseConverter;
  }

这里已经可以获取到我们所有网络请求发起需要的参数了。
接着去看看adapt,这就是网络接口请求返回类型的的适配,比如用的时RxjavaCallAdapter,返回的就是observerble。

网络请求的发起

最后的请求由OkhttpCall来发起。

public void enqueue(final Callback callback) {
 okhttp3.Call call;
call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response response;
        try {
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }
}

这个callBack就是在创建时客户端时那个ExtutorCallback。来完成线程的切换

总结

1.Retrofit将Http请求抽象成java接口
2.接口里用注解 描述和配置网络请求参数
3.动态代理的方式来生成call对象。

你可能感兴趣的:(retrofit原理详解)