retrofit源码分析

作者: 晓晓桑 | 来源:发表于2019-08-17 20:57 被阅读0次

    概述

    image.png

    retrofit是okhttp网络框架的封装。

    • App应用程序通过Retrofit请求网络,实际上是使用Retrofit接口层封装请求参数,之后由okhttp完成后续的请求操作。
    • 在服务端返回数据之后,okhttp将原始的结果交给retrofit,retrofit根据用户的需求对结果进行解析。

    动态代理了解

    https://www.jianshu.com/p/f4208b50f638

    通信八步

    1. 创建retrofit 实例
    2. 定义一个网络请求接口,并为接口中的方法添加注解(get post等)
    3. 通过 动态代理生成网络 请求对象。 其实就是解析网络请求接口中的注解,解析完之后来配置我们的网络请求参数。最终通过动态代理拦截生成网络请求对象的。
    4. 通过 网络请求适配器,将网络请求对象进行平台适配。
    5. 通过 网络请求执行器call 发送网络请求
    6. 通过 数据转化器 解析数据
    7. 通过 回调执行器 切换线程
    8. 用户在主线程处理返回结果

    实现

        public static RetrofitService getRetrofit() {
            Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl(Api.APP_DOMAIN)
                    .addConverterFactory(GsonConverterFactory.create())
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .build();
            retrofitService = retrofit.create(RetrofitService.class);
            return retrofitService;
        }
    
    

    Retrofit 源码---七个成员变量的解释

    public final class Retrofit {
    <-------七个成员变量的解释------>
    //key值:Method: http请求的方法
    //value值:ServiceMethod:注解(网络请求接口中方法的注解)解析之后的对象就是ServiceMethod
    //serviceMethodCache:作用:存储网络请求相关的配置,如网络请求的方法、数据转换器、网络请求适配器、网络请求工厂、基地址等
      private final Map<Method, ServiceMethod<?, ?>> serviceMethodCache = new ConcurrentHashMap<>();
    
      // 网络请求器的工厂
      // 作用:生产网络请求器OkHttpClient
      // Retrofit是默认使用okhttp
      final okhttp3.Call.Factory callFactory;
    
     //网络请求url的基地址
      final HttpUrl baseUrl;
    
    //数据转化器工厂集合:放置数据转换器的工厂
    //工厂的作用是生成我们//数据转化器(converter)
    //数据转化器作用:他对我们请求网络回来的结果response进行转换,把它转换成我们能用的java对象
      final List<Converter.Factory> converterFactories;
    
      // 网络请求适配器工厂的集合, 作用:放置网络请求适配器工厂
      // 网络请求适配器工厂作用:生产网络请求适配器(CallAdapter)
      // CallAdapter适配器作用:把call对象转换成其他类型,比如如果平台想支持rxjava的话,这个时候,可以把call转化成rxjava的call
      final List<CallAdapter.Factory> callAdapterFactories;
    
    //工厂模式:将类实例化的操作与使用对象的操作分开,这样客户端在使用的时候,不需要知道具体的参数,直接通过Factory提供给我们的静态方法就可以创建想要的对象
    
    //用于执行回调,安卓中默认主线程的MainThreadExecutor
      final @Nullable Executor callbackExecutor;
    
    // 标志位
    // 作用:是否提前对业务接口中的注解进行验证转换的标志位
      final boolean validateEagerly;
    }
    

    Retrofit 源码---Retrofit类中的Builder类

    使用Builder的时候,对Retrofit初始化

    public static final class Builder {
        //适配平台:比如android、ios、java8等,默认是android
        private final Platform platform;
        //以下同Retrofit类里面的成员变量的含义
        private @Nullable okhttp3.Call.Factory callFactory;
        private HttpUrl baseUrl;
        private final List<Converter.Factory> converterFactories = new ArrayList<>();
        private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
        private @Nullable Executor callbackExecutor;
        private boolean validateEagerly;
    
    //Builder方法,下面我们看一下Platform.get()
     public Builder() {
          this(Platform.get());
        }
    }
    ...
    
    

    看一下Platform这个类

    class Platform {
      private static final Platform PLATFORM = findPlatform();
    
    <---------1. get()方法,返回的是findPlatform(),看一下findPlatform()------------->
      static Platform get() {
        return PLATFORM;
      }
    
    <---------2. 看一下findPlatform()------------->
      private static Platform findPlatform() {
        try {
        //通过这个类确定是android平台,下面看一下Android();
          Class.forName("android.os.Build");
          if (Build.VERSION.SDK_INT != 0) {
            return new Android();
          }
        } catch (ClassNotFoundException ignored) {
        }
        try {
      //通过这个类确定是java8平台。
          Class.forName("java.util.Optional");
          return new Java8();
        } catch (ClassNotFoundException ignored) {
        }
        return new Platform();
      }
    
      @Nullable Executor defaultCallbackExecutor() {
        return null;
      }
    
      CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
        if (callbackExecutor != null) {
          return new ExecutorCallAdapterFactory(callbackExecutor);
        }
        return DefaultCallAdapterFactory.INSTANCE;
      }
    
      boolean isDefaultMethod(Method method) {
        return false;
      }
    
      @Nullable Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
          @Nullable Object... args) throws Throwable {
        throw new UnsupportedOperationException();
      }
    
      @IgnoreJRERequirement // Only classloaded and used on Java 8.
      static class Java8 extends Platform {
        @Override boolean isDefaultMethod(Method method) {
          return method.isDefault();
        }
    
        @Override Object invokeDefaultMethod(Method method, Class<?> declaringClass, Object object,
            @Nullable Object... args) throws Throwable {
          // Because the service interface might not be public, we need to use a MethodHandle lookup
          // that ignores the visibility of the declaringClass.
          Constructor<Lookup> constructor = Lookup.class.getDeclaredConstructor(Class.class, int.class);
          constructor.setAccessible(true);
          return constructor.newInstance(declaringClass, -1 /* trusted */)
              .unreflectSpecial(method, declaringClass)
              .bindTo(object)
              .invokeWithArguments(args);
        }
      }
    
    <------------3.Android这个类---------------------------->
    // 线程切换是通过一开始创建Retrofit对象时,调用Builder()时,Platform在检测到运行环境是Android时进行创建的
    // 采用适配器模式
      static class Android extends Platform {
        @Override public Executor defaultCallbackExecutor() {
         // 返回一个默认的回调方法执行器
          // 该执行器作用:切换线程(子->>主线程),并在主线程(UI线程)中执行回调方法
    MainThreadExecutor()
          return new MainThreadExecutor();
        }
    
        // 创建默认的网络请求适配器工厂
        // 该默认工厂生产的 adapter 会使得Call在异步调用时在指定的 Executor 上执行回调
        // 在Retrofit中提供了四种CallAdapterFactory: ExecutorCallAdapterFactory(默认)、GuavaCallAdapterFactory、Java8CallAdapterFactory、RxJavaCallAdapterFactory
        // 采用了策略模式
        @Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
          if (callbackExecutor == null) throw new AssertionError();
          return new ExecutorCallAdapterFactory(callbackExecutor);
        }
    
    <------------4.MainThreadExecutor---------------------------->
        static class MainThreadExecutor implements Executor {
    //绑定到主线程的Handler
          private final Handler handler = new Handler(Looper.getMainLooper());
    
          @Override public void execute(Runnable r) {
           // 该Handler是上面获取的与Android 主线程绑定的Handler 
            // 在UI线程进行对网络请求返回数据处理等操作。
            handler.post(r);
          }
        }
      }
    }
    //// 切换线程的流程:
    // 1. 回调ExecutorCallAdapterFactory生成了一个ExecutorCallbackCall对象
    //2. 通过调用ExecutorCallbackCall.enqueue(CallBack)从而调用MainThreadExecutor的execute()通过handler切换到主线程
    
    

    .baseUrl(Api.APP_DOMAIN)方法

    把baseurl转化成适合okhttp请求的url变量,具体如下

      public Builder baseUrl(String baseUrl) {
          //判空
          checkNotNull(baseUrl, "baseUrl == null");
          //string类型转换成HttpUrl类型
          HttpUrl httpUrl = HttpUrl.parse(baseUrl);
          if (httpUrl == null) {
            throw new IllegalArgumentException("Illegal URL: " + baseUrl);
          }
    <-------看下一个类------->
          return baseUrl(httpUrl);
        }
    
    

    上面baseUrl类

        public Builder baseUrl(HttpUrl baseUrl) {
          checkNotNull(baseUrl, "baseUrl == null");
       //依次提取出Path的各个部分的字符串
          List<String> pathSegments = baseUrl.pathSegments();
    //如果baseurl不是以"/"的结尾,就会抛出异常
          if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
            throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
          }
          this.baseUrl = baseUrl;
          return this;
        }
    

    .addConverterFactory(GsonConverterFactory.create())方法

        /** Add converter factory for serialization and deserialization of objects. */
        public Builder addConverterFactory(Converter.Factory factory) {
       //converterFactories对象是retrofit成员变量,上面有讲
        //add添加了一个我们创建的factory:GsonConverterFactory
          converterFactories.add(checkNotNull(factory, "factory == null"));
          return this;
        }
    

    下面看一下GsonConverterFactory.create()方法

      public static GsonConverterFactory create() {
      //看一下以下的creat(Gson gson)方法
        return create(new Gson());
      }
    
      public static GsonConverterFactory create(Gson gson) {
        if (gson == null) throw new NullPointerException("gson == null");
      //接下来看GsonConverterFactory(Gson gson)
        return new GsonConverterFactory(gson);
      }
    
      private final Gson gson;
      private GsonConverterFactory(Gson gson) {
        this.gson = gson;
      }
    

    实际上:GsonConverterFactory.create()创建来一个带Gson gson的实例的GsonConverterFactory对象,然后返回给addConverterFactory()方法。

    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())

     public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
    //callAdapterFactories是retrofit的成员变量,上面说过。
    //作用是将factory:RxJavaCallAdapterFactory.create()添加到callAdapterFactories集合中
          callAdapterFactories.add(checkNotNull(factory, "factory == null"));
          return this;
        }
    

    接下来看一下RxJavaCallAdapterFactory.create()

      public static RxJavaCallAdapterFactory create() {
        return new RxJavaCallAdapterFactory(null, false);
      }
    
      private RxJavaCallAdapterFactory(@Nullable Scheduler scheduler, boolean isAsync) {
        this.scheduler = scheduler;
        this.isAsync = isAsync;
      }
    

    实际上:RxJavaCallAdapterFactory.create()创建来一个带Scheduler scheduler、boolean isAsync的实例的RxJavaCallAdapterFactory对象,然后返回给addCallAdapterFactory()方法。

    .build()方法

       public Retrofit build() {
     //baseurl非空判断
          if (baseUrl == null) {
            throw new IllegalStateException("Base URL required.");
          }
    
          okhttp3.Call.Factory callFactory = this.callFactory;
       //retrofit默认okhttp进行网络请求
          if (callFactory == null) {
            callFactory = new OkHttpClient();
          }
    
    // callbackExecutor 用于线程切换
          Executor callbackExecutor = this.callbackExecutor;
          if (callbackExecutor == null) {
    //默认创建的是主线程的Executor
            callbackExecutor = platform.defaultCallbackExecutor();
          }
    
          //制作适配器的防御性副本
          // Make a defensive copy of the adapters and add the default Call adapter.
          List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    //callAdapterFactories工厂集合添加默认的调用适配器工厂
    callAdapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    
        //创建转换器的防御性副本。
          // Make a defensive copy of the converters.
          List<Converter.Factory> converterFactories =
              new ArrayList<>(1 + this.converterFactories.size());
    
          // 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()对象配置数据转换器工厂(converterFactories)
    // converterFactories是一个存放数据转换器Converter.Factory的数组
    // 配置converterFactories即配置里面的数据转换器
    // BuiltInConverters是一个内置的数据转换器工厂(继承Converter.Factory类)new BuiltInConverters():是为了初始化数据转换器
          converterFactories.add(new BuiltInConverters());
          converterFactories.addAll(this.converterFactories);
    
        //创建Retrofit对象
          return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
              unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
        }
      }
    

    build()方法就是把Retrofit类里面的成员变量都配置完毕。

    RxJavaCallAdapterFactory分析

    RxJavaCallAdapterFactory是继承 abstract class Factory类的,Factory是定义在CallAdapter接口中的

    CallAdapter
    image.png

    作用:CallAdapter将retrofit的call对象转化成java对象,retrofit中的call和okhttp的call不太一样,retrofit的call对okhttp中的call进行了封装。
    具体过程:


    image.png

    关于coverter,他可以根据addConverterFactory进行个性化配置,如果不配置retrofit默认配置GsonConverterFactory

    CallAdapter类源码
    public interface CallAdapter<R, T> {
    //我们所需要的接口数据解析后的类型
      Type responseType();
    
    //T类型是我们需要转换成接口的返回类型,Call:是okhttp的call
      T adapt(Call<R> call);
    
    //当我们addCallAdapterFactory里面的工厂类的时候,里面工程类需要继承Factory这个类。
    abstract class Factory {
    
    //根据接口返回类型、注解类型,得到实际需要的callAdapter
        public abstract @Nullable CallAdapter<?, ?> get(Type returnType, Annotation[] annotations,
            Retrofit retrofit);
      protected static Type getParameterUpperBound(int index, ParameterizedType type) {
          return Utils.getParameterUpperBound(index, type);
        }
    
    //获取接口数据原始类型
        protected static Class<?> getRawType(Type type) {
          return Utils.getRawType(type);
        }
      }
    }
    
    rxjava如何运作

    RxJavaCallAdapterFactory:


    image.png

    RxJavaCallAdapterFactory实现Factory抽象类,用来提供具体的适配逻辑,然后通过addCallAdapterFactory(allAdapter.Factory factory)方法注册CallAdapte,然后调用Factory里面回调回来的get(Type returnType, Annotation[] annotations,Retrofit retrofit)方法获取CallAdapter对象,最后调用CallAdapter的adapt(Call<R> call)方法,这个方法把call请求转化成每一个平台所试用的类型

    get方法

    @Override
      public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    //获取原始数据类型
        Class<?> rawType = getRawType(returnType);
    //下面判断rawType是否是rxjava类型的
        boolean isSingle = rawType == Single.class;
        boolean isCompletable = rawType == Completable.class;
        if (rawType != Observable.class && !isSingle && !isCompletable) {
          return null;
        }
    
        if (isCompletable) {
          return new RxJavaCallAdapter(Void.class, scheduler, isAsync, false, true, false, true);
        }
    
        boolean isResult = false;
        boolean isBody = false;
        Type responseType;
        if (!(returnType instanceof ParameterizedType)) {
          String name = isSingle ? "Single" : "Observable";
          throw new IllegalStateException(name + " return type must be parameterized"
              + " as " + name + "<Foo> or " + name + "<? extends Foo>");
        }
    
        Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
        Class<?> rawObservableType = getRawType(observableType);
        if (rawObservableType == Response.class) {
          if (!(observableType instanceof ParameterizedType)) {
            throw new IllegalStateException("Response must be parameterized"
                + " as Response<Foo> or Response<? extends Foo>");
          }
          responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
        } else if (rawObservableType == Result.class) {
          if (!(observableType instanceof ParameterizedType)) {
            throw new IllegalStateException("Result must be parameterized"
                + " as Result<Foo> or Result<? extends Foo>");
          }
          responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
          isResult = true;
        } else {
          responseType = observableType;
          isBody = true;
        }
    
    //最后会返回一个RxJavaCallAdapter的实现对象
        return new RxJavaCallAdapter(responseType, scheduler, isAsync, isResult, isBody, isSingle,
            false);
      }
    }
    

    接下来就会调RxJavaCallAdapter里面的adapt()方法

    RxJavaCallAdapter类

    final class RxJavaCallAdapter<R> implements CallAdapter<R, Object> {
      private final Type responseType;
      private final @Nullable Scheduler scheduler;
      private final boolean isAsync;
      private final boolean isResult;
      private final boolean isBody;
      private final boolean isSingle;
      private final boolean isCompletable;
    
      RxJavaCallAdapter(Type responseType, @Nullable Scheduler scheduler, boolean isAsync,
          boolean isResult, boolean isBody, boolean isSingle, boolean isCompletable) {
        this.responseType = responseType;
        this.scheduler = scheduler;
        this.isAsync = isAsync;
        this.isResult = isResult;
        this.isBody = isBody;
        this.isSingle = isSingle;
        this.isCompletable = isCompletable;
      }
    
      @Override public Type responseType() {
        return responseType;
      }
    
      @Override public Object adapt(Call<R> call) {
    //被观察者,创建他的实例,将call对象和被观察进行关联
        OnSubscribe<Response<R>> callFunc = isAsync
            ? new CallEnqueueOnSubscribe<>(call)
            : new CallExecuteOnSubscribe<>(call);
    
        OnSubscribe<?> func;
        if (isResult) {
          func = new ResultOnSubscribe<>(callFunc);
        } else if (isBody) {
          func = new BodyOnSubscribe<>(callFunc);
        } else {
          func = callFunc;
        }
        Observable<?> observable = Observable.create(func);
    
        if (scheduler != null) {
    //执行retrofit中的网络请求
          observable = observable.subscribeOn(scheduler);
        }
    
        if (isSingle) {
          return observable.toSingle();
        }
        if (isCompletable) {
          return observable.toCompletable();
        }
        return observable;
      }
    }
    
    

    addCallAdapterFactory总结


    image.png

    获取call对象,执行http请求,retrofit调用call请求,其实最终调用的是okhttp当中的call,只不过retrofit对call进行类封装,然后就可以获取到服务端返回对数据,获取到数据以后调用converter把所需要的对象转化出java对象来。
    每个需要不同的适配器工厂,所以addCallAdapterFactory实现:
    实现CallAdapter.Factory抽象类,然后注册到CallAdapter中,通过Factory的get方法获取CallAdapter对象,CallAdapter对象调用adapter方法,将call请求转化成每个平台所试用的对象类型。

    相关文章

      网友评论

        本文标题:retrofit源码分析

        本文链接:https://www.haomeiwen.com/subject/bghejctx.html