不止是“开餐厅”:从动态代理揭示 Retrofit 的架构精髓

192 阅读4分钟

一句话总结:

Retrofit 的魔法,在于它通过动态代理,将你的 Java 接口“动态翻译”成一个 OkHttp 请求;它本身不执行网络操作,而是作为一个精密的“任务转换层”,优雅地站在你的业务代码和强大的 OkHttp 之间。


第一章:优雅的门面——我们热爱的“餐厅”模型

我们之所以热爱 Retrofit,是因为它提供了一个极其简洁、直观的 API,就像一家分工明确的餐厅:

  • Retrofit (老板): 负责全局配置,如 baseUrl
  • Service 接口 (菜单): 用注解清晰地描述了每一个网络请求“菜品”。
  • Converter (大厨): 负责将服务端的“生食材”(JSON) 加工成我们能用的“菜品”(Java/Kotlin 对象)。
  • CallAdapter (外卖平台): 决定了“上菜”的方式,是传统的 Call(堂食),还是 RxJava 或协程(外卖)。

这个模型非常有助于我们上手使用。但现在,我们要走进后厨,看看“菜单”是如何自动变成“服务员”的。


第二章:揭秘魔法——retrofit.create() 背后的动态代理

当你写下 ApiService service = retrofit.create(ApiService.class); 时,有没有想过,一个没有任何实现的 interface 是如何被实例化的?

答案是 Java 动态代理 (java.lang.reflect.Proxy)

create() 方法并没有真的去“实现”你的接口,而是在运行时,动态地创建了一个代理对象。这个代理对象具备了 ApiService 的所有方法,但当你调用它时,例如 service.getUser(1),会发生以下事情:

  1. 调用被拦截: 你的调用被代理对象内部的一个 InvocationHandler(调用处理器)所拦截。
  2. 信息被捕获: InvocationHandler 会收集这次调用的所有信息:你调用的方法 (getUser) 、方法的注解 (@GET, @Path) 、以及你传入的参数 (1)

结论: 我们拿到的 service 实例,不是一个真正的“服务员”,而是一个聪明的“智能点餐机器人”。它能理解你“点了菜单上的哪道菜”,并把点餐信息记录下来。


第三章:流水线作业——从“接口调用”到“OkHttp 请求”

“智能点餐机器人”拿到点餐信息后,就开始了它的流水线工作:

  1. 解析注解 (一次性工作):

    Retrofit 在第一次调用 getUser 方法时,会通过反射解析该方法的所有注解,并将这些信息(如 HTTP 方法是 GET,路径是 users/{id})缓存到一个 ServiceMethod 对象中。这确保了昂贵的反射操作只进行一次。

  2. 构建请求 (每次调用):

    InvocationHandler 会使用缓存好的 ServiceMethod,结合你本次调用传入的参数 1,像填表格一样,组装出一个完整的、标准的 okhttp3.Request 对象。

  3. 移交运输队 (委托给 OkHttp):

    组装完成后,Retrofit 的工作就基本结束了。它从配置好的 OkHttpClient 实例中,创建一个 okhttp3.Call 对象,并将组装好的 Request 交给它。后续所有的网络连接、数据收发、重试、缓存等,都由 OkHttp 全权负责。


四、可插拔的“大厨”与“外卖平台”——工厂模式的运用

Retrofit 如何能与 Gson、RxJava 等任意第三方库协作?答案是工厂模式

  • Converter.Factory (大厨的认证机构):

    当你添加 GsonConverterFactory 时,你是在告诉 Retrofit:“我聘请了一个拥有‘Gson 厨师证’的机构。以后所有需要将 JSON 转换为对象的任务,都交给这个机构认证过的厨师去做。”

  • CallAdapter.Factory (外卖平台的认证机构):

    当你添加 RxJava2CallAdapterFactory 时,你是在告诉 Retrofit:“我接入了‘RxJava 外卖平台’。如果菜单上的菜品(接口方法)返回值是 Observable,就派 RxJava 的外卖员去送。”

    Kotlin 协程的支持,也是通过一个内置的 CallAdapterFactory 实现的,它能将 Call 适配为 suspend 函数。


五、总结:一个全新的分层架构认知

你的代码 (业务层)Retrofit (适配/翻译层)OkHttp (执行/运输层)
service.getUser(1)1. 动态代理拦截调用
2. 解析注解,构建 OkHttp.Request
3. Converter 准备处理响应
4. CallAdapter 准备转换返回类型
5. 接收 Request
6. 通过拦截器链执行
7. 发起网络通信
8. 返回 Response

通过这个模型,我们能清晰地看到,Retrofit 并非一个大而全的庞然大物,而是一个设计极其精妙的**“适配层” 。它的伟大之处,不在于重新发明了轮子,而在于它用动态代理**、工厂模式等最经典的设计,优雅地填平了“业务层API定义”与“底层HTTP实现”之间的鸿沟。