最近看了Retrofit(2.5.0)的部分源碼,藉此博客記錄下本身對Retrofit的理解,功力善淺,若有錯誤歡迎各位大佬指正。java
Retrofit的請求分爲四步設計模式
採用了構建者模式來構建,避免在構造方法傳入過多參數致使使用者混淆。緩存
public static final class Builder {
private final Platform platform;
private @Nullable okhttp3.Call.Factory callFactory;
private @Nullable HttpUrl baseUrl;
private final List<Converter.Factory> converterFactories = new ArrayList<>();
private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
private @Nullable Executor callbackExecutor;
private boolean validateEagerly;
......省略
}
複製代碼
這裏只貼出了Builder類的成員變量,能夠看出這個類的成員變量很少,也就是說Retrofit的配置並不像okhttp那麼多安全
Builder(Platform platform) {
this.platform = platform;
}
public Builder() {
this(Platform.get());
}
Builder(Retrofit retrofit) {
platform = Platform.get();
callFactory = retrofit.callFactory;
baseUrl = retrofit.baseUrl;
// Do not add the default BuiltIntConverters and platform-aware converters added by build().
for (int i = 1,
size = retrofit.converterFactories.size() - platform.defaultConverterFactoriesSize();
i < size; i++) {
converterFactories.add(retrofit.converterFactories.get(i));
}
// Do not add the default, platform-aware call adapters added by build().
for (int i = 0,
size = retrofit.callAdapterFactories.size() - platform.defaultCallAdapterFactoriesSize();
i < size; i++) {
callAdapterFactories.add(retrofit.callAdapterFactories.get(i));
}
callbackExecutor = retrofit.callbackExecutor;
validateEagerly = retrofit.validateEagerly;
}
複製代碼
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
if (callFactory == null) {
callFactory = new OkHttpClient();
}
Executor callbackExecutor = this.callbackExecutor;
if (callbackExecutor == null) {
callbackExecutor = platform.defaultCallbackExecutor();
}
// Make a defensive copy of the adapters and add the default Call adapter.
List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));
// Make a defensive copy of the converters.
List<Converter.Factory> converterFactories = new ArrayList<>(
1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());
// Add the built-in converter factory first. This prevents overriding its behavior but also
// ensures correct behavior when using converters that consume all types.
converterFactories.add(new BuiltInConverters());
converterFactories.addAll(this.converterFactories);
converterFactories.addAll(platform.defaultConverterFactories());
return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
}
複製代碼
Retrofit的成員變量和Retrofit的內部類Builder裏面的成員變量是基本一致的,這裏就不作闡述了。bash
咱們前面總結的Retrofit簡單異步請求的第三步就是經過調用Retrofit的creat方法來建立RetrofitInterface接口實例。咱們如今來看下內部是如何工做的。 網絡
從上面咱們知道了Retrofit的Creat方法建立了一個動態代理,當咱們調用請求接口方法時,代理的invoke方法便會執行,這時候主要是經過HttpServiceMethod來解析請求接口(RetrofitInterface)中定義的網絡請求方法。因此,我這裏想多多認識HttpServiceMethod。架構
前面咱們提到的Retrofit的loadServiceMethod方法中,用serviceMethodCache來緩存Method實例和對應的HttpServiceMethod實例,而這個HttpServiceMethod實例是經過ServiceMethod的parseAnnotations方法得到的。 dom
parseAnnotations方法首先構建一個RequestFactory實例 這裏一樣是採用了構建者模式 獲取了method的註解,形參類型,形參註解。顯而易見,RequestFactory類就是將咱們在RetroInteface接口中定義的請求方法註解,返回值,參數類型等等進行解析並存儲。咱們接着看ServiceMethod的parseAnnotations方法,接下來是判斷method的返回值是否合法,不能包括可變類型或者通配符,而且不能爲空,不然拋出異常,也就是說咱們的網絡請求方法的返回值不能包括可變類型或者通配符,而且不能爲空。接着繼續調用子類HttpServiceMethod的parseAnnotations方法