• retrofit网络框架源码解析


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

    一、retrofit框架网络请求过程7个步骤:

      1. 添加Retrofit库的依赖,添加网络权限
      1. 创建接收服务器返回数据的类
      1. 创建用于描述网络请求的接口
      1. 创建Retrofit实例
      1. 创建网络请求接口实例
      1. 发送网络请求(同步/异步)
      1. 处理服务器返回的数据

    或者也可以将网络通信归纳成如下八步:

    1. 创建retrofit实例
    2. 定义一个网络请求接口并为接口中的方法添加注解
    3. 通过动态代理生产网络请求对象
    4. 通过网络请求适配器将网络请求对象进行平台适配
    5. 通过网络请求适配器发送网络请求
    6. 通过数据转换器解析数据
    7. 通过回调执行器切换线程
    8. 用户在主线程处理返回结果

    二、代理

    • 静态代理模式:为其他对象提供一种代理,用以控制对这个对象的访问
      在这里插入图片描述

    • 动态代理模式:代理类在程序运行时创建的代理方式
      相比静态代理,动态代理的优势它能很方便的对我们代理类的函数进行统一的处理,不用频繁的修改每一个代理类函数
      (1)jdk动态代理–需要客户端辅助写些接口来操作
      (2)CGLIB–可以直接修改字节码

    • 每个代理类的对象都会关联一个表示内部处理逻辑的InvocationHandler接口的实现

    • invoke方法的参数中可以获取参数

    • invoke方法的返回值被返回给使用者

    三、Retrofit源码解析

    Retrofit中成员变量:

    1. private final Map> serviceMethodCache = new ConcurrentHashMap<>(); //key是Method为http请求的方法,value是ServiceMethod代表网络请求接口中对方法进行注解之后,通过进行解析之后的对象,跟注解中get、put等是成对出现、一一对应的。serviceMethodCache主要用于缓存,存储一些网络请求的相关配置和网络请求的方法、数据转换器、网络请求适配器等等。

    2. final okhttp3.Call.Factory callFactory; //请求网络的OkHttp的工厂,默认为OkHttpClient,该工厂的作用就是生产OkHttpClient

    3. final HttpUrl baseUrl; //网络请求的基地址,跟接口注解中的相对地址可以拼接成一个完整的请求地址

    4. final List converterFactories; //数据转换器工厂的集合,数据转换器就是对请求网络之后得到的Response所进行的转换,转换成应用java对象,默认情况下使用的是GsonCoverterFactory。该集合就是用于放置数据转换器的工厂,同时这个工厂的作用也是用于生产所需要的数据转换器

    5. final List callAdapterFactories; //网络请求适配器的工厂集合,适配器就是把call对象转换成其他类型,比如Rxjava平台的call。该集合就是用于放置网络适配器工厂,同时这个工厂的作用也是用于生产CallAdapter

    6. final @Nullable Executor callbackExecutor; //用于执行回调,在Android平台中,默认使用的是MainThreadExecutor,即主线程中的executor

    7. final boolean validateEagerly; // 表示的是一个标志位,是否需要立即解析接口中的方法,该标志位是用于动态代理中解析定义好接口中的方法和注解当中

    Retrofit内部类Builder的成员变量:

    1. private final Platform platform; //Retrofit适配的平台,包括android、ios、java8,默认情况下使用的是android平台

    2. private @Nullable okhttp3.Call.Factory callFactory; //表示请求网络的okhttp工厂,默认情况下使用的是okhttp来进行网络请求的,默认值为OkHttpClient

    3. private @Nullable HttpUrl baseUrl; //网络请求的Url基地址

    4. private final List converterFactories = new ArrayList<>(); //数据转换器工厂的集合,数据转换器就是对请求网络之后得到的Response所进行的转换,转换成应用java对象,默认情况下使用的是GsonCoverterFactory。该集合就是用于放置数据转换器的工厂,同时这个工厂的作用也是用于生产所需要的数据转换器

    5. private final List callAdapterFactories = new ArrayList<>(); //网络请求适配器的工厂集合,适配器就是把call对象转换成其他类型,比如Rxjava平台的call。该集合就是用于放置网络适配器工厂,同时这个工厂的作用也是用于生产CallAdapter

    6. private @Nullable Executor callbackExecutor; //用于执行回调,在Android平台中,默认使用的是MainThreadExecutor,即主线程中的executor

    7. private boolean validateEagerly; /// 表示的是一个标志位,是否需要立即解析接口中的方法,该标志位是用于动态代理中解析定义好接口中的方法和注解当中
      Builder类中的2~7成员变量跟Retrofit类中的2-7成员变量是一样的

    Retrofit的build()
    作用: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();  //默认使用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 callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
          callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
    
          // Make a defensive copy of the converters.
          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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    CallAdapter
    在这里插入图片描述

    RxJavaCallAdapterFactory
    在这里插入图片描述

    retrofit请求

    • 同步:OkHttpCall.execute()
      在这里插入图片描述

    • 异步:OkHttpCall.enqueue()

    Retrofit采用的设计模式:

      1. 构建者模式
    Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://***.***.com/")  //设置网络请求的url地址,这个是基地址
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  
                    .addConverterFactory(AppGsonConverterFactory.create())  
                    .build();
    
    • 1
    • 2
    • 3
    • 4
    • 5
      1. 工厂模式

    CallAdapter.Factory

    
      /**
       * Creates {@link CallAdapter} instances based on the return type of {@linkplain
       * Retrofit#create(Class) the service interface} methods.
       */
      abstract class Factory {
        /**
         * Returns a call adapter for interface methods that return {@code returnType}, or null if it
         * cannot be handled by this factory.
         */
        public abstract @Nullable CallAdapter get(
            Type returnType, Annotation[] annotations, Retrofit retrofit);
    
        /**
         * Extract the upper bound of the generic parameter at {@code index} from {@code type}. For
         * example, index 1 of {@code Map} returns {@code Runnable}.
         */
        protected static Type getParameterUpperBound(int index, ParameterizedType type) {
          return Utils.getParameterUpperBound(index, type);
        }
    
        /**
         * Extract the raw class type from {@code type}. For example, the type representing {@code
         * List} returns {@code List.class}.
         */
        protected static Class getRawType(Type type) {
          return Utils.getRawType(type);
        }
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    RxJava2CallAdapterFactory和DefaultCallAdapterFactory 继承于CallAdapter.Factory类,并复写get()方法来返回不同的CallAdapter类型

      1. 静态工厂模式
    public class Platform {
      private static final Platform PLATFORM = findPlatform();
      ... ...
      public static Platform get() {
        return PLATFORM;
      }
    ... ...
    
      /** Attempt to match the host runtime to a capable Platform implementation. */
      private static Platform findPlatform() {
        if (isAndroid()) {
          return findAndroidPlatform();
        } else {
          return findJvmPlatform();
        }
      }
      ... ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
      1. 外观/门面设计模式
        定义:外部与一个子系统进行通信,必须通过一个统一外观的对象(也就是门面)来进行。为这个子系统的一组接口提供一个一致的界面。对外提供统一的接口,方便与外部之间的通信
        在这里插入图片描述
    Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://***.***.com/")  //设置网络请求的url地址,这个是基地址
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  
                    .addConverterFactory(AppGsonConverterFactory.create())  
                    .build();
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Retrofit类的设计就是一个外观模式

      1. 策略模式
        在这里插入图片描述
        Retrofit中的CallAdapter采用了策略模式

      策略模式和工厂模式的区别:策略模式强调的是不同对象的策略方法的具体实现,侧重于方法的实现;工厂模式强调的是生产对象

      1. 适配器模式
    Retrofit retrofit = new Retrofit.Builder()
                    .baseUrl("http://***.***.com/")  //设置网络请求的url地址,这个是基地址
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())  //这个地方采用适配器模式  
                    .addConverterFactory(AppGsonConverterFactory.create())   
                    .build();
    
    • 1
    • 2
    • 3
    • 4
    • 5

    CallAdapter类中adapter()方法

      T adapt(Call call);
    
    • 1
      1. 动态代理模式
      public  T create(final Class 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 {
                    // If the method is a method from Object then defer to normal invocation.
                    if (method.getDeclaringClass() == Object.class) {
                      return method.invoke(this, args);
                    }
                    args = args != null ? args : emptyArgs;
                    return platform.isDefaultMethod(method)
                        ? platform.invokeDefaultMethod(method, service, proxy, args)
                        : loadServiceMethod(method).invoke(args);
                  }
                });
      }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
      1. 观察者设计模式
        Call/OkHttpCall --> 被观察者
        异步请求的Callback -->观察者
  • 相关阅读:
    力扣最热一百题——每日温度
    【Unity】XML文件的解析和生成
    湘潭大学 2023年下学期《C语言》作业0x03-循环1 XTU OJ 1094,1095,1096,1112,1113
    人造肉在中国还有未来吗?
    Loguru:一个超酷的Python库
    flask-admin菜鸟学习笔记
    【吃瓜之旅】第五章吃瓜学习
    载银纳米TiO2/壳聚糖水凝胶/pH/GSH响应羧甲基壳聚糖水凝胶和纳米凝胶的制备
    Javaweb安全——JSP Webshell
    什么是腾讯云云硬盘?有哪些优势?应用于哪些场景?
  • 原文地址:https://blog.csdn.net/xuyin1204/article/details/127887418