Retrofit源码重读记录

252 阅读2分钟
Retrofit的核心机制是动态代理,将普通的Java Interface转化成可进行Http请求的实体对象。

Java动态代理,底层是使用反射原理实现,在内存中创建一个“包名+$Proxy+id序号”的代理对象,为接口生成一个代理对象。当调用接口方法时,会执行到InvocationHandler的invoke方法,即每个被代理的接口都对应一个InvocationHandler实例。


Retrofit源码同样适用了Proxy.newProxyInstance创建动态代理对象。这段代码代表了Retrofit的核心。

  • Proxy.newProxyInstance():产生代理接口的实例。仅能代理实现至少一个接口的类

    • ClassLoader:类加载器。即被代理的接口的类加载器。
    • Class[] interface:被代理对象的父接口
    • InvocationHandler:将要在代理中实现的功能写在该对象中
  • InvocationHandler中的invoke方法:调用代理类的任何方法,此方法都会执行

    • Object proxy:代理对象自身的引用。
    • Method method:当前被调用的方法。
    • Object[] args:当前被调用方法用到的参数

Retrofit如何将Java Interface转化成请求实例


首先通过解析Class和Method的Annotation,生成Java Interface接口配置信息;

然后再通过以下代码,利用ServiceMethod的callAdapter,将一个默认的OkHttpCall适配成网络请求实例。

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

适配器具体实现类:


上层网络接口请求类如下定义:

@BaseUrl(CommonApiSites.HTTP_API_XXX_COM)
public interface LiveStreamApiService {

    @RequestInterceptor(CommonHostRequestInterceptor.class)
    @GET("/room/v1/Cover/get_list")
    BiliCall<GeneralResponse<List<RoomUploadCover>>> getCover(@Query("room_id") long room_id, @Query("type") String type);
}

具体调用该网络接口请求:


调用网络请求接口类getCover方法,会转发给动态代理的InvocationHandler 实现类,由它决定处理。

至此,就将定义的Java Interface转换成一个具体的网络请求实例。