Retrofit 核心调用链源码解析:从动态代理到 OkHttp
本文基于 Retrofit 最新源码(2.x),聚焦非协程路径,逐层拆解一个
api.getUser(1)调用背后发生了什么。
目录
- 入口:Retrofit.create() 与动态代理
- 缓存与解析:loadServiceMethod()
- 核心枢纽:HttpServiceMethod.parseAnnotations()
- 运行时触发:invoke() → adapt()
- 完整的调用链回放
- 总结
1. 入口:Retrofit.create() 与动态代理
一切从 retrofit.create(Api::class.java) 开始:
// Retrofit.java
public <T> T create(final Class<T> service) {
validateServiceInterface(service);
return (T) Proxy.newProxyInstance(
service.getClassLoader(),
new Class<?>[] { service },
new InvocationHandler() {
@Override
public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args) {
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
args = args != null ? args : emptyArgs;
return loadServiceMethod(service, method).invoke(proxy, args);
}
});
}
做了什么:
- 通过
Proxy.newProxyInstance为你的 API 接口生成动态代理对象 - 当你调用
api.getUser(1)时,实际上调的是InvocationHandler.invoke(proxy, method, args) invoke里做了两件事:loadServiceMethod(service, method)— 解析方法注解,返回一个ServiceMethod(实际是HttpServiceMethod的子类).invoke(args)— 真正执行请求
这里有一个细节:
method.getDeclaringClass() == Object.class用来过滤toString()、equals()等 Object 方法,不走 Retrofit 流程。
2. 缓存与解析:loadServiceMethod()
// Retrofit.java
ServiceMethod<?> loadServiceMethod(Class<?> service, Method method) {
while (true) {
Object lookup = serviceMethodCache.get(method);
if (lookup instanceof ServiceMethod<?>) {
return (ServiceMethod<?>) lookup; // 缓存命中
}
if (lookup == null) {
Object lock = new Object();
synchronized (lock) {
lookup = serviceMethodCache.putIfAbsent(method, lock);
if (lookup == null) {
// 第一次解析
ServiceMethod<Object> result =
ServiceMethod.parseAnnotations(this, service, method);
serviceMethodCache.put(method, result);
return result;
}
}
}
// 等待其他线程完成解析
synchronized (lookup) {
Object result = serviceMethodCache.get(method);
if (result != null) return (ServiceMethod<?>) result;
}
}
}
做了什么:
- 用
ConcurrentHashMap<Method, Object>做缓存 - 状态流转:
null→lock对象→ServiceMethod实例 - 并发安全:多个线程同时调用同一方法时,只有第一个线程做解析,其他线程等待
- 解析一次,永久复用
解析入口:
// ServiceMethod.java
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Class<?> service, Method method) {
// 1️⃣ 解析方法注解(@GET、@Path、@Query 等)
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, service, method);
// 2️⃣ 校验返回类型
Type returnType = method.getGenericReturnType();
if (Utils.hasUnresolvableType(returnType)) {
throw methodError(method, "Method return type must not include a type variable or wildcard...");
}
if (returnType == void.class) {
throw methodError(method, "Service methods cannot return void.");
}
// 3️⃣ 移交 HttpServiceMethod 做核心处理
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
3. 核心枢纽:HttpServiceMethod.parseAnnotations()
这是整条链路里最关键的方法,负责两件事:匹配 CallAdapter 和 匹配 Converter。
// HttpServiceMethod.java
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
// ─── 第一步:确定 adapterType ───
// 非 suspend 方法直接拿返回值类型
Type adapterType = method.getGenericReturnType();
// ─── 第二步:匹配 CallAdapter ───
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);
// 问 CallAdapter:你要把响应体转成什么类型?
Type responseType = callAdapter.responseType();
// 校验
if (responseType == okhttp3.Response.class) { /* 抛异常 */ }
if (responseType == Response.class) { /* 抛异常 */ }
// ─── 第三步:匹配 Converter ───
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);
// ─── 第四步:打包返回 ───
okhttp3.Call.Factory callFactory = retrofit.callFactory;
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
3.1 匹配 CallAdapter
private static <ResponseT, ReturnT> CallAdapter<ResponseT, ReturnT> createCallAdapter(
Retrofit retrofit, Method method, Type returnType, Annotation[] annotations) {
return (CallAdapter<ResponseT, ReturnT>) retrofit.callAdapter(returnType, annotations);
}
retrofit.callAdapter() 遍历已注册的 CallAdapter.Factory 列表:
// Retrofit.java
public CallAdapter<?, ?> nextCallAdapter(
@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
int start = callAdapterFactories.indexOf(skipPast) + 1;
for (int i = start; i < callAdapterFactories.size(); i++) {
CallAdapter<?, ?> adapter =
callAdapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter; // 第一个能处理的
}
}
throw ... // "找不到 CallAdapter"
}
对 fun getUser(): Call<User> 来说,匹配到的是 DefaultCallAdapterFactory:
// DefaultCallAdapterFactory.java
public @Nullable CallAdapter<?, ?> get(Type returnType, ...) {
if (getRawType(returnType) != Call.class) {
return null; // 不是 Call 就跳过
}
final Type responseType = Utils.getParameterUpperBound(0, (ParameterizedType) returnType);
// ...
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() { return responseType; }
@Override public Call<Object> adapt(Call<Object> call) {
// 默认包一层 ExecutorCallbackCall,回调切主线程
return new ExecutorCallbackCall<>(executor, call);
}
};
}
谁匹配谁:
| 方法声明 | adapterType | 匹配的工厂 |
|---|---|---|
fun getUser(): Call<User> | Call<User> | DefaultCallAdapterFactory |
fun getUser(): Observable<User> | Observable<User> | RxJava2CallAdapterFactory |
fun getUser(): Flow<User> | Flow<User> | Flow AdapterFactory |
工厂按添加顺序遍历,第一个返回非 null 的胜出。
3.2 匹配 Converter
private static <ResponseT> Converter<ResponseBody, ResponseT> createResponseConverter(
Retrofit retrofit, Method method, Type responseType) {
return retrofit.responseBodyConverter(responseType, method.getAnnotations());
}
逻辑和 CallAdapter 类似——遍历 Converter.Factory 列表,找到第一个能处理 ResponseBody → T 的转换器。比如 GsonConverterFactory、MoshiConverterFactory。
3.3 CallAdapted:把一切打包
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;
}
@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
// ⚡ 执行时调这里
return callAdapter.adapt(call);
}
}
⚠️ 两个容易搞混的名字:
| 名称 | 类型 | 职责 |
|---|---|---|
CallAdapter | interface | 转换规则 — 定义如何把 Call<R> 转成 T |
CallAdapted | class | 存规则的盒子 — 继承 HttpServiceMethod,运行时转发给 CallAdapter |
CallAdapted 继承自 HttpServiceMethod,所以它也是 ServiceMethod 的子类。loadServiceMethod 最终缓存的就是它。
4. 运行时触发:invoke() → adapt()
接口方法被调用时,HttpServiceMethod.invoke 被执行:
// HttpServiceMethod.java
@Override
final @Nullable ReturnT invoke(Object[] args) {
// 第一步:创建 OkHttpCall(此时还没发请求)
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
// 第二步:适配返回类型
return adapt(call, args);
}
4.1 OkHttpCall — 延迟执行的包裹
class OkHttpCall<T> implements Call<T> {
private final RequestFactory requestFactory; // 解析好的 @GET/@Path/@Query 等
private final Object[] args; // 方法参数,比如 [1, "张三"]
private final okhttp3.Call.Factory callFactory; // OkHttpClient
private final Converter<ResponseBody, T> responseConverter;
// 构造时不做事,直到 execute() 或 enqueue() 才真正干活
@Override
public void enqueue(Callback<T> callback) {
// 1. 用 requestFactory + args 创建 okhttp3.Request
okhttp3.Request request = requestFactory.create(args);
// 2. 创建真实的 OkHttp Call
okhttp3.Call call = callFactory.newCall(request);
// 3. 发起网络请求
call.enqueue(new okhttp3.Callback() {
@Override public void onResponse(okhttp3.Response rawResponse) {
// 4. 用 responseConverter 把 ResponseBody 转为 T
T body = responseConverter.convert(rawResponse.body());
callback.onResponse(ExecutorCallbackCall.this, Response.success(body));
}
@Override public void onFailure(okhttp3.Call call, IOException e) {
callback.onFailure(ExecutorCallbackCall.this, e);
}
});
}
}
4.2 adapt() — 最终的适配转发
// CallAdapted.adapt
protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
// 调 DefaultCallAdapterFactory 返回的 CallAdapter.adapt
return callAdapter.adapt(call);
// 返回 ExecutorCallbackCall<User>
}
DefaultCallAdapter.adapt 做了什么?
// DefaultCallAdapterFactory 内部
public Call<Object> adapt(Call<Object> call) {
if (executor == null) return call;
return new ExecutorCallbackCall<>(executor, call); // 包一层线程切换
}
ExecutorCallbackCall 的本质:
static final class ExecutorCallbackCall<T> implements Call<T> {
final Executor callbackExecutor; // 主线程 Executor
final Call<T> delegate; // 真正的 OkHttpCall
@Override public void enqueue(Callback<T> callback) {
delegate.enqueue(new Callback<T>() {
@Override public void onResponse(Call<T> call, Response<T> response) {
// 切到主线程回调
callbackExecutor.execute(() -> callback.onResponse(...));
}
@Override public void onFailure(Call<T> call, Throwable t) {
callbackExecutor.execute(() -> callback.onFailure(...));
}
});
}
}
所以当你调 call.enqueue {} 时,实际调用链是:
ExecutorCallbackCall.enqueue { callback }
↓
OkHttpCall.enqueue { 子线程回调 }
↓
OkHttp 子线程拿到响应
↓
responseConverter.convert(responseBody) → User
↓
callbackExecutor.execute { callback.onResponse(user) } // 切回主线程
5. 完整的调用链回放
以 api.getUser(1) 为例,走一遍完整路径:
构建期(一次)
retrofit.create(Api::class.java)
↓ Proxy.newProxyInstance 生成代理对象
api.getUser 被首次调用
↓ Proxy.invoke
↓ loadServiceMethod(getUser)
↓ ServiceMethod.parseAnnotations
↓ HttpServiceMethod.parseAnnotations
├── 匹配 CallAdapter ← DefaultCallAdapterFactory(因为返回 Call<User>)
├── 匹配 Converter ← GsonConverterFactory(因为响应体转 User)
└── new CallAdapted(包含上面两个) ← 缓存起来
运行期(每次调用)
api.getUser(1)
↓ Proxy.invoke(getUser, [1])
↓ loadServiceMethod(getUser) ← 缓存命中,直接返回
↓ ((HttpServiceMethod)serviceMethod).invoke([1])
├── new OkHttpCall(requestFactory, [1], callFactory, gsonConverter)
│ ← 此时只记住了参数,还没发请求
└── callAdapter.adapt(call)
= ExecutorCallbackCall(mainThreadExecutor, okHttpCall)
← 包了一层线程切换
↓ 返回 ExecutorCallbackCall<User>
调用方拿到 Call<User> 后调 .enqueue {}:
call.enqueue { user -> updateUI(user) }
↓ ExecutorCallbackCall.enqueue
↓ OkHttpCall.enqueue
↓ requestFactory.create([1]) → 生成 okhttp3.Request(GET /users/1)
↓ callFactory.newCall(request).enqueue(回调)
↓ OkHttp 异步网络请求
↓ 子线程拿到响应
↓ gsonConverter.convert(responseBody) → User 对象
↓ callbackExecutor.execute { updateUI(user) } ← 切主线程
时序图
调用方 Retrofit CallAdapted DefaultCallAdapter OkHttpCall OkHttp
│ │ │ │ │ │
│ api.getUser(1) │ │ │ │ │
│───────────────►│ │ │ │ │
│ │ loadServiceMethod │ │ │ │
│ │───────────────────►│ │ │ │
│ │ invoke([1]) │ │ │ │
│ │───────────────────►│ │ │ │
│ │ │ new OkHttpCall() │ │ │
│ │ │─────────────────────────────────►│ │
│ │ │ │ │ │
│ │ │ adapt(call) │ │ │
│ │ │─────────────────►│ │ │
│ │ │ │ Executor │ │
│ │ │ │ CallbackCall │ │
│ │ │◄─────────────────│ │ │
│ │◄───────────────────│ │ │ │
│◄───────────────│ │ │ │ │
│ │ │ │ │ │
│ call.enqueue{} │ │ │ │ │
│───────────────────────────────────────────────────────────────────────►│ │
│ │ │ │ │ enqueue(request) │
│ │ │ │ │─────────────────►│
│ │ │ │ │ │
│ │ │ │ │ 网络响应 │
│ │ │ │ │◄────────────────│
│ │ │ │ │ │
│ │ │ │ │ converter │
│ │ │ │ │ convert(body) │
│ │ │ │ │ │
│ 主线程回调 │ │ │ │ │
│◄───────────────│ │ │ │ │
6. 总结
构建期职责
ServiceMethod.parseAnnotations
↓
RequestFactory.parseAnnotations → 解析 @GET/@Path/@Query 等注解
HttpServiceMethod.parseAnnotations
├── createCallAdapter → 匹配返回值对应工厂(Default / RxJava / Flow)
└── createResponseConverter → 匹配响应体转换器(Gson / Moshi / Protobuf)
↓
new CallAdapted(...) → 打包成 ServiceMethod 子类,缓存
运行期职责
invoke(args)
├── new OkHttpCall(args) → 参数准备好,延迟执行
└── adapt(call, args) → CallAdapted → CallAdapter.adapt
→ 包一层线程切换,返回 Call<T>
几个核心设计点
- 构建期一次性解析 — 反射只在首次调用发生,之后从
ConcurrentHashMap缓存取 - 延迟执行 —
OkHttpCall构造时只保存参数,真正网络请求在enqueue/execute时才触发 - 责任链匹配 — CallAdapter 和 Converter 都是遍历工厂列表,第一个返回非 null 的胜出
- 拦截器模式 —
ExecutorCallbackCall是装饰器模式的应用,对调用方透明地切了线程
下一篇预告:协程 suspend 分支的源码解析 — Continuation 如何被识别、伪装、挂起。