源码分析基于 2.7.0
https://juejin.cn/post/7094625579000922126,
主要分析了Retrofit重要的属性以及如何构建。
Retrofit的动态代理
关于什么是动态代理,可以看下我之前写的https://juejin.cn/post/7094611188071268383
在构建完Retrofit对象以后就要生成代理对象,以下是生成代理对象比较常见的代码;
public interface ApiService {
@GET("productList/{userId}")
Call<Bean> getProductList(@Path("userId") String userId);
}
public class RetrofitRequest {
private ApiService mApi;
public void init(Context context) {
......
mApi = retrofit.create(ApiService.class);//1
}
//Retrofit类中
public <T> T create(final Class<T> service) {
......
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() {
......
@Override public @Nullable Object invoke(Object proxy, Method method,
@Nullable Object[] args) throws Throwable {
if (method.getDeclaringClass() == Object.class) {//如果方法是Object定义的方法,则忽略
return method.invoke(this, args);
}
......
return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);//2
}
});
}
- 注释1:利用Retrofit.create生成动态代理对象,ApiService.class是被代理者;
- 注释2:loadServiceMethod获取对应的方法发起网络请求,这里的invoke不是反射;
我们以发送getProductList请求来分析源码
利用生成的代理对象mApi执行getProductList方法,执行到Retrofit.loadServiceMethod
ServiceMethod<?> loadServiceMethod(Method method) {
ServiceMethod<?> result = serviceMethodCache.get(method);//1
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {//2
result = ServiceMethod.parseAnnotations(this, method);
serviceMethodCache.put(method, result);
}
}
return result;
}
- 注释1:从缓存中查找ServiceMethod;
- 注释2:因为是第一次调用getProductList方法,所以需要构建ServiceMethod.parseAnnotations;
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);//1 最后调用下面Builder模式来构建
Type returnType = method.getGenericReturnType();
......
if (returnType == void.class) {//方法定义必须得有返回值
throw methodError(method, "Service methods cannot return void.");
}
·······
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);//2 最后调用下面的静态方法parseAnnotations
}
//RequestFactory类中
Builder(Retrofit retrofit, Method method) {//3
this.retrofit = retrofit;//retrofit对象
this.method = method;//调用的Method,getProductList
this.methodAnnotations = method.getAnnotations();//方法注解,例如@GET("productList/{userId}")
this.parameterTypes = method.getGenericParameterTypes();//方法参数类型,例如String id
this.parameterAnnotationsArray = method.getParameterAnnotations();//参数注解,例如@Query("id")
}
RequestFactory build() {
......
return new RequestFactory(this);
}
//HttpServiceMethod类中
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(//4
Retrofit retrofit, Method method, RequestFactory requestFactory) {
......
adapterType = method.getGenericReturnType();// 返回值
......
CallAdapter<ResponseT, ReturnT> callAdapter =
createCallAdapter(retrofit, method, adapterType, annotations);//返回值适配器
Type responseType = callAdapter.responseType();//返回值 泛型类型
......
Converter<ResponseBody, ResponseT> responseConverter =
createResponseConverter(retrofit, method, responseType);//返回值 泛型解析器
okhttp3.Call.Factory callFactory = retrofit.callFactory;//OKHttpClient
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
}
......
}
- 注释1:调用注释3 构建者模式构建RequestFactory,这是对请求的封装,例如获取方法注解(GET、POST等)、参数注解、请求参数类型,method对getProductList方法的封装,包括方法名;
- 注释2:调用注释4 静态方法构建CallAdapted(HttpServiceMethod内部类),它的父类是ServiceMethod;CallAdapted封装了requestFactory(参数、注解相关)、callFactory(OKHttpClient相关)、responseConverter(返回结果解析相关)、callAdapter(返回值相关);
- 至此,我们得到了一个CallAdapted,它对某个网络请求的封装;loadServiceMethod(method).invoke(args != null ? args : emptyArgs)是发起网络请求,留到下次再分析哈;
loadServiceMethod大体流程
![](https://img.haomeiwen.com/i20808175/59c1b93e503ee45c.png)
总结
- Retrofit运用动态代理,对Java方法进行解析,封装成一个对象CallAdapted方便后续执行网络请求;
- CallAdapted(HttpServiceMethod内部类),它的父类是ServiceMethod;CallAdapted封装了requestFactory(参数、注解相关)、callFactory(OKHttpClient相关)、responseConverter(返回结果解析相关)、callAdapter(返回值相关);
以上分析有不对的地方,请指出,互相学习,谢谢哦!
网友评论