1. 阅读引导
在分析 源码之前,你首先得理解动态代理模式,因为Retrofit是通过动态代理的方式进行统一网络请求接口类的处理。Retrofit的代码量并不大,只是对OkHttp进行了封装,用更少的代码进行网络请求,明白动态代理模式之后,再看Retrofit网络请求处理流程就很清楚了。少量的代码使用大量的设计模式,所以Retrofit框架很值得我们去研究。
2. Retrofit基本使用
- 配置Retrofit对象(与OkHttp相同,采用Builder模式)
Retrofit retrofit = new Retrofit.Builder().baseUrl("xxxxx").build();
- 创建请求接口类
public interface NetworkInterface { @GET("...") CalllistRepos(); //不同的方法代表不同的网络请求,可以声明请求方式(GET、POST..),请求头Header参数,请求体信息。 ....}复制代码
- 创建接口类实例
NetworkInterface networkInterface = retrofit.create(NetworkInterface.class);
- 调用方法,请求实际的网络请求
Callcall = networkInterface.listRepos(); call.enqueue(new Callback () { //与OkHttp不同,异步请求会回调到主线程 @Override public void onResponse(Call call, Response response) { } @Override public void onFailure(Call call, Throwable t) { } });复制代码
3. Retrofit流程图
说明: 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进行线程切换,上面有讲过! } ListadapterFactories = new ArrayList<>(this.adapterFactories); // 此处将Android平台对象中的CallAdapterFactory添加到Retrofit的CallAdapterFactory集合中. // 注意同时将Executor也传入到这个CallAdapterFactory中,那么工厂生产出来的CallAdapter就也就具有线程切换的能力。 adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor)); List converterFactories = new ArrayList<>(this.converterFactories); return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories, callbackExecutor, validateEagerly); // 通过Builder创建Retrofit,并将配置参数作为参数传入 }复制代码
再看看一下Retrofit的构造:
Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl, ListconverterFactories, List 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);
publicT create(final Class 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
总结: (一 ) retrofit.create(xx)方法中处理分三步:
-
- 判断网络请求接口类的合法性
-
- 是否需要提前对 网络请求接口类 中的方法进行预处理
-
- 返回生成动态代理类
(二) 调用网络请求接口方法,动态代理类中的invoke()方法被执行,也处理也分三步:
-
- 将对应的执行方法转化成ServiceMethod对象
-
- 创建OkHttpCall对象
- 3 OkHttpCall通过CallAdapter进行Call的转化
4.3 调用接口方法
Call 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 CallAdaptercreateCallAdapter() { Type returnType = method.getGenericReturnType(); ... Annotation[] annotations = method.getAnnotations(); ... return (CallAdapter ) 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>() { @Override public Type responseType() { return responseType; } @Override public Call adapt(Call call) { return new ExecutorCallbackCall<>(callbackExecutor, call); } }; }复制代码
总结: ServiceMethod通过Builder模式创建,包含了Retrofit对象,对执行的Method进行剖析,像方法注解、参数注解、参数类型、CallAdapter、ConvertAdapter,所以一个ServiceMethod对象包含了网络请求需要的所有信息。
-
- 创建OkHttpCall对象
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
OkHttpCall.class
OkHttpCall(ServiceMethodserviceMethod, @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>() { @Override public Type responseType() { return responseType; } @Override public Call adapt(Call call) { return new ExecutorCallbackCall<>(callbackExecutor, call); } };复制代码 接着定位返回的CallAdapter中adapt()方法,最后返回了一个new ExecutorCallbackCall<>(callbackExecutor, call); 对象,代表serviceMethod.callAdapter.adapt(okHttpCall);的执行结束,并向外暴露一个ExecutorCallbackCall对象。
- 同步异步网络请求
// 同步请求call.execute();// 异步请求call.enqueue(new Callback() { //与OkHttp不同,异步请求会回调到主线程 @Override public void onResponse(Call call, Response response) { } @Override public void onFailure(Call call, Throwable t) { } });复制代码 与同步相比,异步相对来说复杂一点点,这里只分析异步,相信异步看懂了,同步肯定不在话下。
ExecutorCallbackCall.class
@Override public void enqueue(final Callbackcallback) { ... delegate.enqueue(new Callback () { // delegate是由serviceMethod.callAdapter.adapt(okHttpCall); 传入的,所以最终的网络请求还是通过OkHttpCall进行。 @Override public void onResponse(Call call, final Response 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 call, final Throwable t) { callbackExecutor.execute(new Runnable() { @Override public void run() { callback.onFailure(ExecutorCallbackCall.this, t); } }); } }); }复制代码 OkHttpCall.class
@Override public void enqueue(final Callbackcallback) { ... call.enqueue(new okhttp3.Callback() { // 这个Call才是OKHttp中正宗的Call @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) throws IOException { Response response; try { response = parseResponse(rawResponse); } catch (Throwable e) { callFailure(e); return; } callSuccess(response); } ... }复制代码 5. Retrofit设计模式
- Builder模式
- 外观模式
- 静态工厂模式
- 动态工厂模式
- 适配器模式
- 动态代理模式