当前位置 博文首页 > 2.5.0源码分析_高远的博客:Retrofit

    2.5.0源码分析_高远的博客:Retrofit

    作者:[db:作者] 时间:2021-09-06 22:38

    Retrofit_2.5.0源码分析

    基于Retrofit:3.12.0:https://github.com/square/retrofit/tree/parent-2.5.0

    RTFSC

    Read The Fucking Source Code

    流程分析

    1. 用户层面调用形式:
    
    @NonNull
    protected Retrofit.Builder createBuilder() {
        return new Retrofit.Builder().baseUrl(apiBaseUrl())
            .addConverterFactory(GsonConverterFactory.create(GsonUtils.getGson()))
            .addCallAdapterFactory(RxJava2CallAdapterFactory.createWithScheduler(Schedulers.io()))
            .client(okHttpClient());
        }
    
    //原始call形式
    Call api1=Retrofit#create(final Class<T> service).api()
    api1.enqueue(Callback<T>)
    
    //Rxjava形式
    Obserable api2=Retrofit#create(final Class<T> service).api()
    api2.subscibe{T t}
    
    
    1. Retrofit#create(final Class service):Retrofit典型的面向接口编程入口。传递进来我们定义的API(接口形式)。可以明显看出,首先检测传递进来的是否是接口,否则直接抛异常:throw new IllegalArgumentException("API declarations must be interfaces.")。接着执行是否提前初始化缓存该接口中所有的API方法。即使我们没有看下面的代码,也可以猜测出会和下面的方法有部分逻辑重合,因为"提前"初始化。先跳过提前初始化这一块逻辑,因为是个性化业务。直接看重点动态代理。注意:InvocationHandler#invoke的返回值就是我们定义的API的返回:Call或者Obserable,所以loadServiceMethod(method).invoke(args != null ? args : emptyArgs)=>ServiceMethod#invoke的返回值也就是Call或者Obserable,后面分析会用到。
    //Retrofit
    public <T> T create(final Class<T> service) {
        //检测service是否是接口,不是直接抛异常
        Utils.validateServiceInterface(service);
        //是否提前遍历缓存service中所有的接口
        if (validateEagerly) {
          eagerlyValidateMethods(service);
        }
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
            new InvocationHandler() {
              @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
                //其它辅助代码...
                //核心入口:返回值就是我们定义的API的返回值
                return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
              }
            });
      }
    
    1. 动态代理,单独拿出来介绍一下。loader:代理对象的类加载器;interfaces代理对象数组;InvocationHandler#invoke:proxy代理对象的引用;method:接口中对应的方法;args:方法中的参数;返回值:Object就是method对应的返回值。
    Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
    
    public interface InvocationHandler {
        public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable;
    }                                          
    
    
    1. InvocationHandler#invoke=>Retrofit#loadServiceMethod#invoke=>ServiceMethod#invoke:首先根据method作为key检查是否在缓存中,存在直接返回;否则ServiceMethod#parseAnnotations去根据方法解析。进行下面分析前,我们回想一下,这里的"method"指的是什么?对的,就是我们在接口中定义的API,ServiceMethod.parseAnnotations(this, method)是核心,那会做些什么?根据名字可以猜测:解析参数、注解、返回值…继续看,是否和我们猜测一致。
        //Retrofit
       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;
      }
    
    1. Retrofit#loadServiceMethod=>ServiceMethod#parseAnnotations(retrofit, method)=>RequestFactory.parseAnnotations=>RequestFactory#build():目的:解析方法的注解、参数注解、以及参数。这里会调用RequestFactory.parseAnnotations(retrofit, method)生成RequestFactory对象。parseAnnotations根据下面的RequestFactory#Builder可以看出主要遍历方法注解和参数注解存到RequestFactory中,方便后续使用。
    abstract class ServiceMethod<T> {
     static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
       //根据method解析method参数、注解、返回值生成RequestFactory对象
       RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    
       //这里先不看,下面再分析...
       return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
     }
    }
    
    RequestFactory#Builder
    RequestFactory build() {
          //解析方法上面的注解    
          for (Annotation annotation : methodAnnotations) {
            parseMethodAnnotation(annotation);
          }
    
          //...
            
          //解析方法参数中的注解        
          int parameterCount = parameterAnnotationsArray.length;
          parameterHandlers = new ParameterHandler<?>[parameterCount];
          for (int p = 0; p < parameterCount; p++) {
            parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);
          }
    
          //...
    
          return new RequestFactory(this);
        }
        
        RequestFactory#Builder
        private void parseMethodAnnotation(Annotation annotation) {
          //解析方法上的注解,不同的类型请求
          if (annotation instanceof DELETE) {
            parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
          } else if (annotation instanceof GET) {
            parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
          } ...其它类型的请求
        }
        
        //解析参数注解,要遍历每个参数,因为每个参数都可能有注解
        private ParameterHandler<?> parseParameter(
            int p, Type parameterType, @Nullable Annotation[] annotations) {
          ParameterHandler<?> result = null;
          if (annotations != null) {
            for (Annotation annotation : annotations) {
              ParameterHandler<?> annotationAction =
                  parseParameterAnnotation(p, parameterType, annotations, annotation);
    
              ...
          }
         ...
          return result;
        }
        
        //解析参数注解:贼长的遍历解析,写框架不仅需要架构经验,还是一个体力活
        @Nullable
        private ParameterHandler<?> parseParameterAnnotation(
            int p, Type type, Annotation[] annotations, Annotation annotation) {
          if (annotation instanceof Url) {
            ...
          } else if (annotation instanceof Path) {
            ...
          } else if (annotation instanceof Query) {
            ...
          } else ...
    
          return null; // Not a Retrofit annotation.
        }
    
    
    1. ServiceMethod#parseAnnotations=>HttpServiceMethod#parseAnnotations=>HttpServiceMethod#createCallAdapter:目的:解析方法的返回值,确认CallAdapter。
    #ServiceMethod
    abstract class ServiceMethod<T> {
      static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
        //上一步有分析
        RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    
        //...
        
        //入口,生成HttpServiceMethod对象
        return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
      }
    
    
    }
      
    
    //HttpServiceMethod#parseAnnotations
    static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
          Retrofit retrofit, Method method, RequestFactory requestFactory) {
        //重点:入口
        CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
        
        //...
    
        //根据callAdapter构建Converter包装类
        Converter<ResponseBody, ResponseT> responseConverter =
            createResponseConverter(retrofit, method, responseType);
    
        okhttp3.Call.Factory callFactory = retrofit.callFactory;
        //构建HttpServiceMethod
        return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
      }
      
      //HttpServiceMethod
      private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
          Retrofit retrofit, Method method) {
          Type returnType = method.getGenericReturnType();
          //根据返回值获取CallAdapter
          return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
      }
    
    
    1. HttpServiceMethod#createCallAdapter=>Retrofit#callAdapter:目的:遍历callAdapterFactories寻找CallAdapter,只要不为null就符合条件。
     //Retrofit
     public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
        return nextCallAdapter(null, returnType, annotations);
      }
      
      // Retrofit
      public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
          Annotation[] annotations) {
        //...
        
        //遍历callAdapterFactories,这个是我们设置retrofit的时候Retrofit#Builder#addCallAdapterFactory
        int start = callAdapterFactories.indexOf(skipPast) + 1;
        for (int i = start, count = callAdapterFactories.size(); i < count; i++) {
          CallAdapter<?, ?> adapter = callAdapterFactories.get(i).get(returnType, annotations, this);
          if (adapter != null) {
            return adapter;
          }
        }
    
       //...
      }
    
    1. InvocationHandler#invoke=>ServiceMethod#invoke=>HttpServiceMethod#invokeCallAdapter#adapt=>RxJava2CallAdapter#adapt:目的:获取返回值,回溯到动态代理,结束。下面是RxJava2CallAdapter的一个实现,我们可以看出返回值就是类似Obserable这种形式。
    //ServiceMethod
    abstract class ServiceMethod<T> {
      //动态代理最后调用的方法
      abstract T invoke(Object[] args);
    }
    
    final class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
      //最终动态代理调用的方法        
      @Override ReturnT invoke(Object[] args) {
        return callAdapter.adapt(
            new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
      }
    }
    
    
    //RxJava2CallAdapter,这是一个CallAdapter其中的一个实现
    final class RxJava2CallAdapter<R> implements CallAdapter<R, Object> {
     
      @Override public Object adapt(Call<R> call) {
        //这里取做真正的调用
        Observable<Response<R>> responseObservable = isAsync
            ? new CallEnqueueObservable<>(call)
            : new CallExecuteObservable<>(call);
    
        Observable<?> observable;
        if (isResult) {
          observable = new ResultObservable<>(responseObservable);
        } else if (isBody) {
          observable = new BodyObservable<>(responseObservable);
        } else {
          observable = responseObservable;
        }
    
        if (scheduler != null) {
          observable = observable.subscribeOn(scheduler);
        }
    
        if (isFlowable) {
          return observable.toFlowable(BackpressureStrategy.LATEST);
        }
        if (isSingle) {
          return observable.singleOrError();
        }
        if (isMaybe) {
          return observable.singleElement();
        }
        if (isCompletable) {
          return observable.ignoreElements();
        }
        return RxJavaPlugins.onAssembly(observable);
      }
    }
    
    
    final class CallEnqueueObservable<T> extends Observable<Response<T>> {
      private final Call<T> originalCall;
    
      CallEnqueueObservable(Call<T> originalCall) {
        this.originalCall = originalCall;
      }
    
      @Override protected void subscribeActual(Observer<? super Response<T>> observer) {
        // Since Call is a one-shot type, clone it for each new observer.
        Call<T> call = originalCall.clone();
        CallCallback<T> callback = new CallCallback<>(call, observer);
        observer.onSubscribe(callback);
        if (!callback.isDisposed()) {
          //最后的call API    
          call.enqueue(callback);
        }
      }
    
    
    

    参考

    1. https://github.com/square/retrofit
    2. https://www.jianshu.com/p/cb444f49a777
    cs
    下一篇:没有了