Retrofit原理浅析

来源:互联网 发布:淘宝10元包邮入住 编辑:程序博客网 时间:2024/05/12 01:39

类库原理解析

注解

Retrofit使用注解+java接口来定义后台服务API接口

注解主要分为 方法注解 和 参数注解

注解类型作用@GET方法注解表明HTTP请求方法为GET,(可选)注解的value属性用来设置相对/绝对url@POST方法注解表明HTTP请求方法为POST,(可选)注解的value属性用来设置相对/绝对url@PUT方法注解表明HTTP请求方法为PUT,(可选)注解的value属性用来设置相对/绝对url@DELETE方法注解表明http请求方法为DELETE,(可选)注解的value属性用来设置相对/绝对url@PATCH方法注解表明HTTP请求方法为PATCH,(可选)注解的value属性用来设置相对/绝对url@HEAD方法注解表明HTTP请求方法为HEAD,(可选)注解的value属性用来设置相对/绝对url@OPTIONS方法注解表明HTTP请求方法为OPTIONS,(可选)注解的value属性用来设置相对/绝对url@HTTP方法注解通过@HTTP注解指定http协议的请求方法,是否允许body,(可选)注解的value属性用来设置相对/绝对url@FormUrlEncoded方法注解表明发起HTTP请求的RequestBody是form表单方式@Multipart方法注解表明发起HTTP请求的RequestBody是Multipar方式@Headers方法注解使用注解的value值数组作为HTTP请求的头,用于一些固定的Header参数@Streaming方法注解用于需要直接返回流的函数@Url参数注解HTTP请求的url路径(相对/绝对),可以包含{path_holder},如:http://xxx.com/{user_holder}/detail@Path参数注解用于动态替换URL路径中的path_holder@Body参数注解表明此参数用作HTTP请求的body@Field参数注解表明此参数用作HTTP请求的form表单参数,key为注解的value值@FieldMap参数注解以map形式传入的form表单参数@Header参数注解表明此参数用作HTTP请求的header,key为注解的value值@HeaderMap参数注解以map形式传入的多个header键值对@Part参数注解表明参数为Http的multipart参数之一@PartMap参数注解以map形式传入的multipart参数表@Query参数注解GET方法的query参数,用于拼接完整请求路径@QueryMap参数注解以map传入的GET方法的query参数,用于拼接完整请求路径

调用流程

通过上面代码可以看到调用关键的就是三步:

  • 1 加载对应method的ServiceMethod实例
  • 2 使用ServiceMethod实例和方法调用参数创建OkHttpCall
  • 3 调用serviceMethod.callAdapter.adapt(okHttpCall)来产生method所定义的返回(Call<T>或者其他自定义CallAdapter支持的返回)

第一步、加载对应method的ServiceMethod实例

ServiceMethod中有以下四个变量比较重要

final okhttp3.Call.Factory callFactory;final CallAdapter<?> callAdapter;private final Converter<ResponseBody, T> responseConverter;private final ParameterHandler<?>[] parameterHandlers;
  • callFactory是用来创建真正要执行的okhttp3.Call的工厂类,可以Retrofit.Builder中设置,如果不设置,默认会new一个OkHttpClient作为callFactory
  • callAdapter是用来最终处理OkHttpCall实例并返回接口Method所定义的返回
  • responseConverter 用来将Http请求的结果转换成接口Method所定义的结果(return或者Callback<T>中的T)
  • parameterHandlers 根据接口Method参数的注解所生成的参数处理Handler数组

然后我们来看Retrofit.loadServiceMethod方法

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

可以看到此处先检查serviceMethodCache是否有该method对应的ServiceMethod实例缓存,如果没有,则创建一个该method

对应的ServiceMethod实例并保存到缓存中。

ServiceMethod的创建使用的是建造者模式。

在ServiceMethod.Builder的build方法中,通过解析传入的method的方法定义(参数类型,返回类型,参数注解,方法注解)生成

对应的callAdapter,responseConverter,parameterHandlers及其他一些创建请求需要用到的信息。

    public ServiceMethod build() {      callAdapter = createCallAdapter();      ......检查返回结果类型......      responseConverter = createResponseConverter();      //生成方法注解的处理器      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, parameterType, parameterAnnotations);      }      ......方法与注解合法性检查......      return new ServiceMethod<>(this);    }

此处在ServiceMethod.Builder.build()过程在生成过程中还会对method的定义做合法性检查,如:http方法是get就不允许方法参数中有body类型的参数;

方法为post则必须有参数为Body类型。

第二步、使用ServiceMethod实例和方法调用参数创建OkHttpCall

获取到method对应的ServiceMethod实例后,会使用该ServiceMethod实例和方法调用的参数Object... args生成一个OkHttpCall。

而OkHttpCall实际上是okhttp3.Call的一个包装类

,实际调用OkHttpCall的相关执行方法时最终是调用OkHttpCall内部用ServiceMethod.callFactory创建的okhttp3.Call来执行网络请求。

第三步、调用serviceMethod.callAdapter.adapt(okHttpCall)来产生method所定义的返回

Retrofit2默认支持的返回是返回一个Call<T>,利用此Call<T>实例可执行

Response<T> result = call.execute();//同步执行


//异步执行call.enqueue(new Callback(){    public void onResponse(Call<T> call, Response<T> response){        //TODO     }    public void onFailure(Call<T> call, Throwable t){        //TODO     }   });

其中在Android平台Retrofit2会自动使用主线程handler构造一个ExecutorCallAdapterFactory,调用enqueue(Callback),callback回调会在主线程中回调

另外在Retrofit的扩展Adapter中还提供了RxJavaCallAdapterFactory,Java8CallAdapterFactory,GuavaCallAdapterFactory

以RxJavaCallAdapterFactory为例,RxJavaCallAdapterFactory创建的callAdapter在执行adapt时将OkHttpCall包装一个Rx的Observable,在Observable被subscribe时才会真正的执行http请求。

原创粉丝点击