Retrofit2分析<一> Retrofit 类分析

本文深入剖析Retrofit2的工作原理,从create方法入手,详细解释动态代理、RequestFactory构造及HttpServiceMethod的生成过程。同时,探讨了OkHttpCall、响应转换器及CallAdapter的角色,最终聚焦于CallAdapted类的invoke方法。

从public T create(final Class service) 入手,此方法属于外部核心入口。一般接收一个接口的Class,然后构造出来一个继承Class的实例。我们一般通过Retrofit.Builder的方式构造retrofit实例,通过retrofit.create的方式构造我们最终需要利用的请求类。实在是好的一逼。

mHttpApiService = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(FastJsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.client(okHttpClient)
.build()
.create(mHttpApiService.getClass());

可以看到retrofit2天然是需要配合okhttp 使用的,因为client 入参是OkHttpClient。比较难点是理解 addCallAdapterFactory 这个方法。我们先保留这个疑问 。现在回到create方法。
public T create(final Class service) {
//这一步检查Class是否合法,是否是接口,是否只有一个接口,不允许接口继承接口。

Utils.validateServiceInterface(service);
if (validateEagerly) {
  eagerlyValidateMethods(service);
}
//此为一个动态代理。目的其实就是充实接口的行为。具体可以看loadServiceMethod(method).invoke(args != null ? args : emptyArgs)这个。
  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);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }

//loadServiceMethod 此方法会构造一个HttpServiceMethod。然后进行调用。

 ServiceMethod<?> loadServiceMethod(Method method) {
 //缓存机制。
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
      //具体构造HttpServiceMethod。是一个静态构造方法。
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

//此方法很关键。

 static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
    //此方法会解析method的所有注解,构造RequestFactory 。
    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.");
    }
    //最终构造,注意传入的参数。
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

//到了最终构造方法,之前传入的参数在这里会有得到利用。我会去掉一些分支,对于分析骨干意义不大。

 static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
     adapterType = method.getGenericReturnType();
     //获取method的返回类型。接下来判断返回类型是否合法。
        if (responseType == okhttp3.Response.class) {
      throw methodError(method, "'"
          + getRawType(responseType).getName()
          + "' is not a valid response body type. Did you mean ResponseBody?");
    }
    if (responseType == Response.class) {
      throw methodError(method, "Response must include generic type (e.g., Response<String>)");
    }
    //	创建Converter,最终拿的的是FastJsonConverterFactory.create() 这个地方传入的对象。
       Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);
      //  此处callFactory 我们并没有传入,是用的系统自动创建。new OkHttpClient() 对象。
       okhttp3.Call.Factory callFactory = retrofit.callFactory;    
       // 最终落脚方法,利用了之前有传入的有构造的。requestFactory,callFactory,responseConverter,callAdapter 分析源码就是这样,有点类似捉迷藏游戏。没办法。代码本质上实际就是一个工程,类似盖房子,这里盖一点,那里盖一点,的确很繁琐,不过房子盖好了住起来舒服。框架也是一样,麻烦也是为了最终的好用。
          return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
  }           

//继续,看到CallAdapted 实际上是集成了HttpServcieMethod。然后构造方法也是传入变量而已。

  
  static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT,ReturnT> {
    private final CallAdapter<ResponseT, ReturnT> callAdapter;
    CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
        Converter<ResponseBody, ResponseT> responseConverter,
        CallAdapter<ResponseT, ReturnT> callAdapter) {
      super(requestFactory, callFactory, responseConverter);
      this.callAdapter = callAdapter;
    }
}

//最终我们使用Retrofit2的时候基本上是,类似下面这种
Observable<Response<BaseResponse<List>>> getDictMaps(@Nullable@QueryMap Map<String, Object> paramString);
mHttpApiService.getDictMaps(paramString)
基本上是直接调用。因为我们知道最终getDictMaps 是被代理了。调用的实际上是CallAdapted 的invoke方法。getDictMaps 包括注解在类的信息已经完全注解过去了。我们且看下这个方法,retrofit2会如何使用。

 @Override final @Nullable ReturnT invoke(Object[] args) {
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }

此方法为final不允许覆盖。首先构造OkHttpCall 然后

  @Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
      return callAdapter.adapt(call);
    }
callAdataper就是最初传入的 RxJava2CallAdapterFactory.create() 。OkHttpCall 是okHttp实际的请求类。RxJava2CallAdapterFactory.create() 是构造 了一个RxJava2CallAdapter。调用adapter方法。这个留在下面一篇文章来分析。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值