美文网首页
retrofit原理详解

retrofit原理详解

作者: remax1 | 来源:发表于2020-07-24 17:11 被阅读0次

    前言

      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<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
      //网络请求器工厂
      final okhttp3.Call.Factory callFactory;
      //网络请求适配器器工厂集合
      final List<CallAdapter.Factory> callAdapterFactories;
      //数据转换器工厂集合
       final List<Converter.Factory> converterFactories;
      //回调方法执行器
      final @Nullable Executor callbackExecutor;
    
      Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
          List<Converter.Factory> converterFactories, List<CallAdapter.Factory> 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<Converter.Factory> converterFactories = new ArrayList<>();
        private final List<CallAdapter.Factory> 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<? extends CallAdapter.Factory> 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<? extends Converter.Factory> defaultConverterFactories() {
          return Build.VERSION.SDK_INT >= 24
              ? singletonList(OptionalConverterFactory.INSTANCE)
              : Collections.<Converter.Factory>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<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
          Retrofit retrofit) {
        TypeAdapter<?> adapter = gson.getAdapter(TypeToken.get(type));
        return new GsonResponseBodyConverter<>(gson, adapter);
      }
    
      @Override
      public Converter<?, RequestBody> 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<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
          callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
    
          // 配置数据转换器工厂
          List<Converter.Factory> 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<Bean> getCall();
    }
    
      //使用了外观模式,通过传入class可以对每一个网络请求接口的访问
      Service service = retrofit.create(Service.class);
    
      Call<Bean> call = service.getCall();
    

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

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

     public <T> T create(final Class<T> 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 <T> ServiceMethod<T> 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<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
      //解析参数
      static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
          Retrofit retrofit, Method method, RequestFactory requestFactory) {
        CallAdapter<ResponseT, ReturnT> 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<ResponseBody, ResponseT> responseConverter =
            createResponseConverter(retrofit, method, responseType);
    
        okhttp3.Call.Factory callFactory = retrofit.callFactory;
        return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
      }
    
          //去遍历网络请求适配工厂
      // //网络接口方法的返回值类型来确定合适的CallAdapter实例
      private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
          Retrofit retrofit, Method method) {
        Type returnType = method.getGenericReturnType();
        Annotation[] annotations = method.getAnnotations();
        try {
          //noinspection unchecked
          return (CallAdapter<ResponseT, ReturnT>) 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 <ResponseT> Converter<ResponseBody, ResponseT> 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<ResponseT, ReturnT> callAdapter;
      private final Converter<ResponseBody, ResponseT> responseConverter;
    
      private HttpServiceMethod(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
          CallAdapter<ResponseT, ReturnT> callAdapter,
          Converter<ResponseBody, ResponseT> 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<ResponseBody, T> responseConverter) {
        this.requestFactory = requestFactory;
        this.args = args;
        this.callFactory = callFactory;
        this.responseConverter = responseConverter;
      }
    

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

    网络请求的发起

    最后的请求由OkhttpCall来发起。

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

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

    总结

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

    相关文章

      网友评论

          本文标题:retrofit原理详解

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