Retrofit 核心调用链源码解析:从动态代理到 OkHttp

65 阅读6分钟

Retrofit 核心调用链源码解析:从动态代理到 OkHttp

本文基于 Retrofit 最新源码(2.x),聚焦非协程路径,逐层拆解一个 api.getUser(1) 调用背后发生了什么。


目录

  1. 入口:Retrofit.create() 与动态代理
  2. 缓存与解析:loadServiceMethod()
  3. 核心枢纽:HttpServiceMethod.parseAnnotations()
  4. 运行时触发:invoke() → adapt()
  5. 完整的调用链回放
  6. 总结

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 里做了两件事:
    1. loadServiceMethod(service, method) — 解析方法注解,返回一个 ServiceMethod(实际是 HttpServiceMethod 的子类)
    2. .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);
    }
}

⚠️ 两个容易搞混的名字:

名称类型职责
CallAdapterinterface转换规则 — 定义如何把 Call<R> 转成 T
CallAdaptedclass存规则的盒子 — 继承 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>

几个核心设计点

  1. 构建期一次性解析 — 反射只在首次调用发生,之后从 ConcurrentHashMap 缓存取
  2. 延迟执行 — OkHttpCall 构造时只保存参数,真正网络请求在 enqueue/execute 时才触发
  3. 责任链匹配 — CallAdapter 和 Converter 都是遍历工厂列表,第一个返回非 null 的胜出
  4. 拦截器模式 — ExecutorCallbackCall 是装饰器模式的应用,对调用方透明地切了线程

下一篇预告:协程 suspend 分支的源码解析 — Continuation 如何被识别、伪装、挂起。