1. 阅读引导
在分析 Retrofit 源码之前,你首先得理解动态代理模式,因为Retrofit是通过动态代理的方式进行统一网络请求接口类的处理。Retrofit的代码量并不大,只是对OkHttp进行了封装,用更少的代码进行网络请求,明白动态代理模式之后,再看Retrofit网络请求处理流程就很清楚了。少量的代码使用大量的设计模式,所以Retrofit框架很值得我们去研究。
2. Retrofit基本使用
- 配置Retrofit对象(与OkHttp相同,采用Builder模式)
Retrofit retrofit = new Retrofit.Builder().baseUrl("xxxxx").build();
- 创建请求接口类
public interface NetworkInterface {
@GET("...")
Call<MyResponse> listRepos(); //不同的方法代表不同的网络请求,可以声明请求方式(GET、POST..),请求头Header参数,请求体信息。
....
}
- 创建接口类实例
NetworkInterface networkInterface = retrofit.create(NetworkInterface.class);
- 调用方法,请求实际的网络请求
Call<MyResponse> call = networkInterface.listRepos();
call.enqueue(new Callback<MyResponse>() { //与OkHttp不同,异步请求会回调到主线程
@Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) { }
@Override
public void onFailure(Call<MyResponse> call, Throwable t) { }
});
3. Retrofit流程图
Retrofit请求处理流程图.PNG说明: Retrofit只存在一个CallFactory,但是存在多个CallAdapterFactory和ConvertFactory,针对不同的请求接口方法,Retrofit会通过其返回值,选择特定的CallAdapterFactory和CovertFactory。
4. Retrofit源码分析
4.1 Retrofit创建过程
通过前面基本的使用代码可以看出,Retrofit的创建也是采用Builder设计模式,通过new Retrofit.Builder().build()。我们先看看new Retrofit.Builder()的初始化工作。
public static final class Builder {
...
public Builder() {
this(Platform.get());
}
Builder(Platform platform) {
converterFactories.add(new BuiltInConverters());
}
...
}
通过Platform.get()获取当前平台对象Platform,然后调用它的另一个构造器,在这个构造器中,为ConvertFactory集合添加一个默认的ConvertFactory,不同的ConvertFactory产生的Convert对OkHttp网络请求返回的Response转化处理不一样,而默认ConvertFactory的Convert并没有对Response做太多处理,获得的数据依旧是Response对象。通过Builder.addConverterFactory(xxx)添加更多的ConvertFactory,比如xxx替换为GsonConverterFactory.create()添加GsonConvertFatory,它产生的GsonConvert就能将Response映射成JavaBean实体。
回到主流程,还是看看Platform.get()是如何处理的吧!
class Platform {
private static final Platform PLATFORM = findPlatform(); // 静态工厂模式!
static Platform get() {
return PLATFORM;
}
private static Platform findPlatform() { // 识别当前平台,如果是Android,就直接返回Android()对象实例
try {
Class.forName("android.os.Build");
if (Build.VERSION.SDK_INT != 0) {
return new Android();
}
} catch (ClassNotFoundException ignored) {
}
...
static class Android extends Platform { // Platform的子类,Android平台对象类
@Override public Executor defaultCallbackExecutor() {
return new MainThreadExecutor();
}
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) { // 获取Android平台的默认CallAdapterFactory对象
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
static class MainThreadExecutor implements Executor { // 获取Android平台的默认线程执行调度器,其实就是通过Handler用于线程切换。
private final Handler handler = new Handler(Looper.getMainLooper());
@Override public void execute(Runnable r) {
handler.post(r);
}
}
}
}
总结: 通过new Retrofit.Builder()为ConvertFactory集合中添加一个默认ConvertFactory,创建一个包含默认的CallAdapterFactory、Executor的Android平台对象。注意,默认的ConvertFactory已经添加到了ConvertFactory集合中了,但是Android对象中的CallAdapterFactory并没有加入到CallAdapterFactory集合中。
接着看new Retrofit.Builder().build()中的build()方法:
public Retrofit build() {
if (baseUrl == null) { // 强制需要通过.baseUrl("xxxxx")配置url
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient(); // 创建CallFactory用于生产Call对象,从这里也可以看出Retrofit最终还是通过OkHttp发送网络请求
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor(); // 获取Android平台对象中的默认Executor,里面通过Handler进行线程切换,上面有讲过!
}
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
// 此处将Android平台对象中的CallAdapterFactory添加到Retrofit的CallAdapterFactory集合中.
// 注意同时将Executor也传入到这个CallAdapterFactory中,那么工厂生产出来的CallAdapter就也就具有线程切换的能力。
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly); // 通过Builder创建Retrofit,并将配置参数作为参数传入
}
再看看一下Retrofit的构造:
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
List<Converter.Factory> converterFactories, List<CallAdapter.Factory> adapterFactories,
@Nullable Executor callbackExecutor, boolean validateEagerly) {
this.callFactory = callFactory;
this.baseUrl = baseUrl;
this.converterFactories = unmodifiableList(converterFactories); // Defensive copy at call site.
this.adapterFactories = unmodifiableList(adapterFactories); // Defensive copy at call site.
this.callbackExecutor = callbackExecutor;
this.validateEagerly = validateEagerly;
}
4.2 核心动态代理代码
NetworkInterface networkInterface = retrofit.create(NetworkInterface.class);
public <T> T create(final Class<T> service) {
Utils.validateServiceInterface(service); // 1. 判断网络请求接口类的合法性
if (validateEagerly) { // 2. 是否需要提前对 网络请求接口类 中的方法进行提前处理,即为接口中的每一个方法提前处理成 SeviceMethod(核心类)对象,并缓存。
eagerlyValidateMethods(service);
}
// 3. 生成动态代理类
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, @Nullable Object[] args)
throws Throwable {
...
// 4. 将接口中的方法处理成serviceMethod。
ServiceMethod<Object, Object> serviceMethod = (ServiceMethod<Object, Object>) loadServiceMethod(method);
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args); // 5. 创建 OkHttpCall对象,传入serviceMethod对象和调用方法实际参数。
return serviceMethod.callAdapter.adapt(okHttpCall); // 6. 将Call对象进行CallAdapter进行转化( 比如RxCallAdapter将Call转化为Observable ) 注意Call还没有被执行,即没有进行网络请求。
}
});
}
总结:
(一 ) retrofit.create(xx)方法中处理分三步:
- 判断网络请求接口类的合法性
- 是否需要提前对 网络请求接口类 中的方法进行预处理
- 返回生成动态代理类
(二) 调用网络请求接口方法,动态代理类中的invoke()方法被执行,也处理也分三步:
- 将对应的执行方法转化成ServiceMethod对象
- 创建OkHttpCall对象
- 3 OkHttpCall通过CallAdapter进行Call的转化
4.3 调用接口方法
Call<MyResponse> call = networkInterface.listRepos();
在通过上面的说明,当调用网络请求接口类方法时,就会调用invoke方法,传入通过反射获取Method和执行方法参数args,因为没有调用call.execute()或call.enqueue(Callback),所以Call并没有执行。接下来我们具体看看invoke方法体中三部曲吧!
- 将对应的执行方法转化成ServiceMethod对象
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method); // 先从缓存中取,如果在之前分析的create()中validateEagerly = true 必然从缓存中能取到。
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build(); // 根据Method创建ServiceMethod对象
serviceMethodCache.put(method, result); // 将创建的ServiceMethod进行缓存
}
}
return result;
}
接下来看看,ServiceMethod的创建!
ServiceMethodBuilder.class
Builder(Retrofit retrofit, Method method) {
this.retrofit = retrofit; // 1. 将外观类 Retrofit传入
this.method = method;
this.methodAnnotations = method.getAnnotations(); // 2. 获取方法上的注解(@GET @POST... )
this.parameterTypes = method.getGenericParameterTypes();
this.parameterAnnotationsArray = method.getParameterAnnotations(); // 3. 获取参数注解(@Query ...)
}
public ServiceMethod build() {
callAdapter = createCallAdapter(); // 4. 获取该方法对应的CallAdapter
responseType = callAdapter.responseType(); // 5. 获取该方法的响应类型,比如Response或者自定义的JavaBean
...
responseConverter = createResponseConverter(); // 6. 根据上面获取的响应类型获取对应的Convert
for (Annotation annotation : methodAnnotations) { // 7. 解析第二步得到的方法注解
parseMethodAnnotation(annotation);
}
...
int parameterCount = parameterAnnotationsArray.length;
parameterHandlers = new ParameterHandler<?>[parameterCount];
for (int p = 0; p < parameterCount; p++) {
Type parameterType = parameterTypes[p];
...
Annotation[] parameterAnnotations = parameterAnnotationsArray[p]; // 8. 解析第三步得到的参数注解
...
parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
}
return new ServiceMethod<>(this); // 创建ServiceMethod对象
}
之前有说过Retrofit中可以有多个ConvertFactory和CallAdapterFactory,通过上面的第4步和第6步获取该Method对应的ConvertFactory和CallAdapterFactory。这两种Factory的适配过程近乎一样,所以这里只做CallAdapterFactory的配对过程。
private CallAdapter<T, R> createCallAdapter() {
Type returnType = method.getGenericReturnType();
...
Annotation[] annotations = method.getAnnotations();
...
return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
}
Retrofit.class
public CallAdapter<?, ?> nextCallAdapter(@Nullable CallAdapter.Factory skipPast, Type returnType, Annotation[] annotations) {
// type: return 返回的类型,比如Call、Observable
...
int start = adapterFactories.indexOf(skipPast) + 1; // 用于做CallAdapterFactory跳过处理,默认start = 0
for (int i = start, count = adapterFactories.size(); i < count; i++) {
CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
if (adapter != null) {
return adapter;
}
}
...
}
每一个CallAdapterFactory需要实现一个get(returnType,xxx)方法,如果能处理这个returnType就返回对应的CallAdapter对象。比如默认returnType为Call,那么就被默认的CallAdapterFactory接受处理,这个CallAdapterFactory在Android平台类中defaultCallAdapterFactory()获得(4.1 Retrofit创建过程 有说明)
Android.class
@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
if (callbackExecutor == null) throw new AssertionError();
return new ExecutorCallAdapterFactory(callbackExecutor);
}
ExecutorCallAdapterFactory.class
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
final Executor callbackExecutor;
ExecutorCallAdapterFactory(Executor callbackExecutor) {
this.callbackExecutor = callbackExecutor;
}
@Override
public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
if (getRawType(returnType) != Call.class) {
return null;
}
final Type responseType = Utils.getCallResponseType(returnType);
return new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
}
总结: ServiceMethod通过Builder模式创建,包含了Retrofit对象,对执行的Method进行剖析,像方法注解、参数注解、参数类型、CallAdapter、ConvertAdapter,所以一个ServiceMethod对象包含了网络请求需要的所有信息。
- 创建OkHttpCall对象
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
OkHttpCall.class
OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
this.serviceMethod = serviceMethod;
this.args = args;
}
- 3 OkHttpCall通过CallAdapter进行Call的转化
serviceMethod.callAdapter.adapt(okHttpCall);
如果接口方法返回类型是Call的话,CallAdapter就是默认的CallAdaterFactory创建的CallAdapter,即ExecutorCallAdapterFactory类中get()方法返回的CallAdapter:
new CallAdapter<Object, Call<?>>() {
@Override public Type responseType() {
return responseType;
}
@Override public Call<Object> adapt(Call<Object> call) {
return new ExecutorCallbackCall<>(callbackExecutor, call);
}
};
接着定位返回的CallAdapter中adapt()方法,最后返回了一个new ExecutorCallbackCall<>(callbackExecutor, call); 对象,代表serviceMethod.callAdapter.adapt(okHttpCall);的执行结束,并向外暴露一个ExecutorCallbackCall对象。
- 同步异步网络请求
// 同步请求
call.execute();
// 异步请求
call.enqueue(new Callback<MyResponse>() { //与OkHttp不同,异步请求会回调到主线程
@Override
public void onResponse(Call<MyResponse> call, Response<MyResponse> response) { }
@Override
public void onFailure(Call<MyResponse> call, Throwable t) { }
});
与同步相比,异步相对来说复杂一点点,这里只分析异步,相信异步看懂了,同步肯定不在话下。
ExecutorCallbackCall.class
@Override public void enqueue(final Callback<T> callback) {
...
delegate.enqueue(new Callback<T>() { // delegate是由serviceMethod.callAdapter.adapt(okHttpCall); 传入的,所以最终的网络请求还是通过OkHttpCall进行。
@Override public void onResponse(Call<T> call, final Response<T> response) {
callbackExecutor.execute(new Runnable() { // callbackExecutor 是Android平台对象类中的MainThreadExecutor 主要将线程切换到主线程
@Override public void run() {
if (delegate.isCanceled()) {
...
} else {
callback.onResponse(ExecutorCallbackCall.this, response);
}
}
});
}
@Override public void onFailure(Call<T> call, final Throwable t) {
callbackExecutor.execute(new Runnable() {
@Override public void run() {
callback.onFailure(ExecutorCallbackCall.this, t);
}
});
}
});
}
OkHttpCall.class
@Override public void enqueue(final Callback<T> callback) {
...
call.enqueue(new okhttp3.Callback() { // 这个Call才是OKHttp中正宗的Call
@Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
throws IOException {
Response<T> response;
try {
response = parseResponse(rawResponse);
} catch (Throwable e) {
callFailure(e);
return;
}
callSuccess(response);
}
...
}
5. Retrofit设计模式
- Builder模式
- 外观模式
- 静态工厂模式
- 动态工厂模式
- 适配器模式
- 动态代理模式
网友评论