zoukankan      html  css  js  c++  java
  • Retrofit源码解析

    知识点:

    代理模式、反射

    1:用法:

    public interface TestApi {
        @GET("search")
        Observable<List<TestImage>> search(@Query("q") String query);
    } 
    public interface TestApi {
        @GET("search")
        Observable<List<TestImage>> search(@Query("q") String query);
    }
    private static OkHttpClient okHttpClient = new OkHttpClient();
        private static Converter.Factory gsonConverterFactory = GsonConverterFactory.create();
        private static CallAdapter.Factory rxJavaCallAdapterFactory = RxJava2CallAdapterFactory.create();
    
        public static TestApi getTestApi() {
            if (testApi == null) {
                Retrofit retrofit = new Retrofit.Builder()
                        .client(okHttpClient)
                        .baseUrl("http://www.zhuangbi.info/")
                        .addConverterFactory(gsonConverterFactory)
                        .addCallAdapterFactory(rxJavaCallAdapterFactory)
                        .build();
                testApi = retrofit.create(TestApi.class);
            }
            return testApi;
        }

    getTestApi().search("test")。。。。
    .subscribe(items->{
    ......
    );
     

    2:总体流程:

    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() {
              private final Platform platform = Platform.get();
    
              @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);
                }
                ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.callAdapter.adapt(okHttpCall);
              }
            });
      }

    以上这段代码用到了动态代理模式,所谓动态代理模式,就是只要知道了一个类的字节码文件.class,就能得到该类的方法和属性。

    通常代理模式有一个被委托类,代理类以及一个interface,代理类持有被委托类,被委托类被调用的所有方法都将转换为invoke执行。

    该代码中interface有了,代理类也有了,但是代理类并没有去持有被委托类,而是利用代理模式的这种特性去执行其他操作:

    ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.callAdapter.adapt(okHttpCall);

    先看loadServiceMethod(method)

    ServiceMethod<?, ?> loadServiceMethod(Method method) {
        ServiceMethod<?, ?> result = serviceMethodCache.get(method);
        if (result != null) return result;
    
        synchronized (serviceMethodCache) {
          result = serviceMethodCache.get(method);
          if (result == null) {
            result = new ServiceMethod.Builder<>(this, method).build();
            serviceMethodCache.put(method, result);
          }
        }
        return result;
      }

    最重要的是:result = new ServiceMethod.Builder<>(this, method).build();

    这里返回一个Servicemethod的类:

    public ServiceMethod build() {
          callAdapter = createCallAdapter();
          responseType = callAdapter.responseType();
          if (responseType == Response.class || responseType == okhttp3.Response.class) {
            throw methodError("'"
                + Utils.getRawType(responseType).getName()
                + "' is not a valid response body type. Did you mean ResponseBody?");
          }
          responseConverter = createResponseConverter();
    
          for (Annotation annotation : methodAnnotations) {
            parseMethodAnnotation(annotation);
          }
    
          if (httpMethod == null) {
            throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
          }
    
          if (!hasBody) {
            if (isMultipart) {
              throw methodError(
                  "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
            }
            if (isFormEncoded) {
              throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
                  + "request body (e.g., @POST).");
            }
          }
    
          int parameterCount = parameterAnnotationsArray.length;
          parameterHandlers = new ParameterHandler<?>[parameterCount];
          for (int p = 0; p < parameterCount; p++) {
            Type parameterType = parameterTypes[p];
            if (Utils.hasUnresolvableType(parameterType)) {
              throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
                  parameterType);
            }
    
            Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
            if (parameterAnnotations == null) {
              throw parameterError(p, "No Retrofit annotation found.");
            }
    
            parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
          }
    
          if (relativeUrl == null && !gotUrl) {
            throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
          }
          if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
            throw methodError("Non-body HTTP method cannot contain @Body.");
          }
          if (isFormEncoded && !gotField) {
            throw methodError("Form-encoded method must contain at least one @Field.");
          }
          if (isMultipart && !gotPart) {
            throw methodError("Multipart method must contain at least one @Part.");
          }
    
          return new ServiceMethod<>(this);
        }

    以上这段代码主要有两个作用:

    1:得到callAdapter供给前面的 return serviceMethod.callAdapter.adapt(okHttpCall);使用

    callAdapter = createCallAdapter();
    private CallAdapter<T, R> createCallAdapter() {
          。。。。。。。。。。
          Annotation[] annotations = method.getAnnotations();
          try {
            //noinspection unchecked
            return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
    。。。。。。。。。
        }
     public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
        return nextCallAdapter(null, returnType, annotations);
      }
    public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType,
          Annotation[] annotations) {
        。。。。。。。。。。。。。int start = adapterFactories.indexOf(skipPast) + 1;
        for (int i = start, count = adapterFactories.size(); i < count; i++) {
          CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
          if (adapter != null) {
            return adapter;
          }
        }
    。。。。。。。。。
    }

    serviceMethod.callAdapter.adapt(okHttpCall);可以看到这里所需的callAdapter在这个地方拿到:

    CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
    adapterFactories是属于Retrofit类的,通过查找可以知道是通过
    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
          adapterFactories.add(checkNotNull(factory, "factory == null"));
          return this;
        }

    添加进来的,而这个正式应用层添加的:

      Retrofit retrofit = new Retrofit.Builder()
                        .client(okHttpClient)
                        .baseUrl("http://www.zhuangbi.info/")
                        .addConverterFactory(gsonConverterFactory)
                        .addCallAdapterFactory(rxJavaCallAdapterFactory)
                        .build();

    所以我们找到了:RxJava2CallAdapterFactory

    前面我们分析到:CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);

    所以serviceMethod.callAdapter.adapt(okHttpCall);这里的adapter是:

    RxJava2CallAdapterFactory的get方法得到:

    public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        Class<?> rawType = getRawType(returnType);
    
        。。。。。。。return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
            isSingle, isMaybe, false);
      }

    所以最终锁定到:

    RxJava2CallAdapter:
    然后执行adapt:

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

     以上过程中:

    Rxjava2CallAdapter持有OkHttpCall, OKHttpCall持有method,method持有Retrofit的各种信息,继续往下走:

    看Rxjava2CallAdapter的adapt:

    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;
        }
    
      。。。。。。。。。。
    return observable; }

    这里生成了CallEnqueueObservable,并持有OkHttpCall,这时候回到最开始的地方:

    getZhuangbiApi().search("装逼")。。。。
    .subscribe(items->{
    ......
    );
     这里的getZhuangbiApi()就是CallEnqueueObservable,我们代码跟进subcribe:
    public final void subscribe(Observer<? super T> observer) {
            ObjectHelper.requireNonNull(observer, "observer is null");
            try {
                observer = RxJavaPlugins.onSubscribe(this, observer);
    
                ObjectHelper.requireNonNull(observer, "Plugin returned null Observer");
    
                subscribeActual(observer);
            。。。。。。。
            }
        }
    
    

    会发现这里有个subscribeActual,我们就知道这里执行的是CallEnqueueObservable的subscribeActual:

    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);
        call.enqueue(callback);
      }

    绕了一圈,又回到了OkhttpCall这个类,执行enqueue:

    public void enqueue(final Callback<T> callback) {
        checkNotNull(callback, "callback == null");
    
        okhttp3.Call call;
        Throwable failure;
    
        synchronized (this) {
          if (executed) throw new IllegalStateException("Already executed.");
          executed = true;
    
          call = rawCall;
          failure = creationFailure;
          if (call == null && failure == null) {
            try {
              call = rawCall = createRawCall();
            } catch (Throwable t) {
              failure = creationFailure = t;
            }
          }
        }
    
        if (failure != null) {
          callback.onFailure(this, failure);
          return;
        }
    
        if (canceled) {
          call.cancel();
        }
    
        call.enqueue(new okhttp3.Callback() {
          @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
              throws IOException {
            Response<T> response;
            try {
              response = parseResponse(rawResponse);
            } catch (Throwable e) {
              callFailure(e);
              return;
            }
            callSuccess(response);
          }
    
          @Override public void onFailure(okhttp3.Call call, IOException e) {
            try {
              callback.onFailure(OkHttpCall.this, e);
            } catch (Throwable t) {
              t.printStackTrace();
            }
          }
    
          private void callFailure(Throwable e) {
            try {
              callback.onFailure(OkHttpCall.this, e);
            } catch (Throwable t) {
              t.printStackTrace();
            }
          }
    
          private void callSuccess(Response<T> response) {
            try {
              callback.onResponse(OkHttpCall.this, response);
            } catch (Throwable t) {
              t.printStackTrace();
            }
          }
        });
      }
     3:动态代理
    前面说到动态代理,我们传进来的是一个interface,如何产生一个代理类呢:
    public static Object newProxyInstance(ClassLoader loader,
                                              Class<?>[] interfaces,
                                              InvocationHandler h)
            throws IllegalArgumentException
        {
            Objects.requireNonNull(h);
    
            final Class<?>[] intfs = interfaces.clone();
            。。。。。
            Class<?> cl = getProxyClass0(loader, intfs);
    
           。。。。。。。。。。。
    
                final Constructor<?> cons = cl.getConstructor(constructorParams);
                final InvocationHandler ih = h;
                if (!Modifier.isPublic(cl.getModifiers())) {
                    // Android-changed: Removed AccessController.doPrivileged
                    cons.setAccessible(true);
                }
                return cons.newInstance(new Object[]{h});
            } catch (IllegalAccessException|InstantiationException e) {
                。。。。。。。。。。。。。
        }
    
    

    这个主要看的一个方法是:

    private static Class<?> getProxyClass0(ClassLoader loader,
                                               Class<?>... interfaces) {
            if (interfaces.length > 65535) {
                throw new IllegalArgumentException("interface limit exceeded");
            }
    
            // If the proxy class defined by the given loader implementing
            // the given interfaces exists, this will simply return the cached copy;
            // otherwise, it will create the proxy class via the ProxyClassFactory
            return proxyClassCache.get(loader, interfaces);
        }

    可以看到Class是由proxyClassCache的get得到的,再去找proxyClassCache

    
    
     private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
            proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
    
    
    这里我们找到:ProxyClassFactory:
    private static final class ProxyClassFactory
            implements BiFunction<ClassLoader, Class<?>[], Class<?>>
        {
           。。。。。。。。。。。。。
    。。。。。。。。。。。。。。。
    /* * Choose a name for the proxy class to generate. */ long num = nextUniqueNumber.getAndIncrement(); String proxyName = proxyPkg + proxyClassNamePrefix + num; return generateProxy(proxyName, interfaces, loader, methodsArray, exceptionsArray); } } }
    
    

    最主要的是最后几行代码:

    long num = nextUniqueNumber.getAndIncrement();
                    String proxyName = proxyPkg + proxyClassNamePrefix + num;
    
                    return generateProxy(proxyName, interfaces, loader, methodsArray,
                                         exceptionsArray);

    generateProxy是一个native的方法,所以代理类的字节码最终是由这里产生的。

    该字节码的名字格式为:proxyPkg + proxyClassNamePrefix + num,

    即:包名+$Proxy+num

    然后通过newProxyInstance方法里面的:

    return cons.newInstance(new Object[]{h});

    生成动态代理类返回。
     
     
  • 相关阅读:
    安装centos虚拟机
    关于区别广播域与冲突域
    网络七层架构
    怎么有效避免黑客使用跳板软件进行攻击窃取信息数据
    C语言猜数字游戏
    页置换算法FIFO、LRU、OPT
    Samza的ApplicationMaster
    Samza文档翻译 : Comparison Introduction
    Samza文档翻译 : Architecture
    Samza文档翻译 : Concepts
  • 原文地址:https://www.cnblogs.com/wnpp/p/13970918.html
Copyright © 2011-2022 走看看