正文
关于上面种种奇怪的类,我们先不关心,因为之后我们遇到了再分析。我们先把目光聚焦在
Retrofit
类上。
Retrofit
Retrofit
类的构造方法没什么好看的,在这就不讲了。
得到
Retrofit
对象后就是调用
create(final Class<T> service)
方法来创建我们 API 接口的实例。
所以我们需要跟进
create(final Class<T> service)
中来看下:
public <T> T create(final Class<T> service) {
// 校验是否为接口,且不能继承其他接口
Utils.validateServiceInterface(service);
// 是否需要提前解析接口方法
if (validateEagerly) {
eagerlyValidateMethods(service);
}
// 动态代理模式
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
private final Platform platform = Platform.get();
@Override public Object invoke(Object proxy, Method method, Object... args)
throws Throwable {
// If the method is a method from Object then defer to normal invocation.
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
// 将接口中的方法构造为 ServiceMethod
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
在上面的代码中,最关键的就是动态代理。实际上,进行网络操作的都是通过代理类来完成的。如果对动态代理不太懂的同学请自行百度了,这里就不多讲了。
重点就是
// 将接口中的方法构造为 ServiceMethod
ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);
这三句代码,下面我们着重来看。
在代理中,会根据参数中传入的具体接口方法来构造出对应的
serviceMethod
。
ServiceMethod
类的作用就是把接口的方法适配为对应的 HTTP call 。
ServiceMethod loadServiceMethod(Method method) {
ServiceMethod result;
synchronized (serviceMethodCache) {
// 先从缓存中取,若没有就去创建对应的 ServiceMethod
result = serviceMethodCache.get(method);
if (result == null) {
// 没有缓存就创建,之后再放入缓存中
result = new ServiceMethod.Builder(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
可以看到在内部还维护了一个
serviceMethodCache
来缓存
ServiceMethod
,以便提高效率。我们就直接来看
ServiceMethod
是如何被创建的吧。
ServiceMethod.Builder
发现
ServiceMethod
也是通过建造者模式来创建对象的。那就进入对应构造方法: