声明式请求

声明式请求

Posted by candy1126xx on May 7, 2017

重要的类

RealCall是OkHttp中描述一次请求过程的类。

OkHttpCall是RealCall的装饰类,扩展了构造Request对象的方法,和对Response对象的处理。

ServiceMethod是“扩展”的具体实现,即用动态代理实现声明式请求,用适配者模式实现对RealCall/Response对象的转换。

动态代理

在运行时动态地为实现类创建代理对象,以控制对执行者的访问。

主要构成:

  • 功能接口:定义暴露方法。
  • 实现类:实现了功能接口,真正处理逻辑的类。
  • 扩展类:实现InvocationHandler接口,在实现类成员方法调用前后添加处理逻辑的类。
  • 代理类:运行时调用Proxy.newProxyInstance()生成的代理类。

使用场景:

声明式请求

用户只需声明“功能接口”,用注解配置参数。在运行时,Retrofit会使用动态代理,自动生成代理对象。当代理对象的成员方法被调用时,解析注解,构造出OkHttpCall对象。在这个过程中没有实现类。

转化过程

在Retrofit.create(service)中,service为功能接口的Class对象:

  1. 返回Proxy.newProxyInstance(),即代理对象,其中;
  2. 第一个参数,service.getClassLoader,即当前虚拟机的ClassLoader;
  3. 第二个参数,功能接口,即service。
  4. 第三个参数,实现了InvocationHandler接口的匿名内部类。在其invoke()中:
    • 把Method对象和Retrofit对象封装为ServiceMethod对象,在这个过程中,解析注解,为ServiceMethod对象的成员变量赋值。
    • 把ServiceMethod对象放入Retrofit.serviceMethodCache缓存。
    • 把ServiceMethod对象封装为OkHttpCall对象。

适配者模式

创建一个类作为两个不兼容的接口之间的桥梁,使用户在调用1个接口的成员方法时,实质上是在调用另1个接口的方法。

主要构成:

  • 对外接口和对内接口:待适配的两个接口。
  • 桥梁:把对“对外接口”的成员方法的调用,转换为对“对内接口”的成员方法的调用。

RxJavaCallAdapter

RxJavaCallAdapter可以把OkHttpCall对象适配为Observable对象。

  • 对外接口:Observable。
  • 对内接口:Call。
  • 桥梁:一个实现了CallAdapter接口的对象。

创建桥梁

桥梁用工厂模式创建,创建过程在Retrofit.nextCallAdapter()中,其中,第一个参数是null,第二个参数是service功能接口的成员方法的返回类型,第三个参数是service功能接口的成员方法的注解。

  1. 遍历Retrofit.adapterFactories,调用元素的get()方法,若返回的不是null,即得到了“桥梁”。
  2. Retrofit.adapterFactories是一个List,其中CallAdapter.Factory是创建“桥梁”的抽象类。
  3. 可以在配置Retrofit阶段,调用Retrofit.addCallAdapter()向Retrofit.adapterFactories添加元素。
  4. 如果要实现把OkHttpCall对象转换为Observable对象,就需要写一个继承CallAdapter.Factory的类RxJavaCallAdapterFactory,重写get()。
  5. 在get()中返回一个RxJavaCallAdapter对象,即“桥梁”。

适配过程

RxJavaCallAdapter对象的适配过程在RxJavaCallAdapter.adapter()中: