Retrofit 是对 OkHttp 网络库的封装,真正的网络请求是通过 OkHttp 完成的
Retrofit 涉及到的设计模式
构建模式、代理模式、工厂模式、适配器模式
源码分析要点
- 使用构建模式创建 Retrofit 实例对象
- 使用代理模式创建网络请求接口的代理类
- 解析网络接口的注解,生成 ServiceMethod 对象
- 通过工厂模式及 Method 信息生成网络请求适配器和内容解析器
- 通过适配器模式适配 Call 接口,并返回对应的类型(Completable、Deferred)
- 网络结果返回时,在 ServiceMethod#toResponse 方法中通过解析器生成具体的返回值
使用 Retrofit 时,需要先创建一个 Retrofit 实例
private fun createRetrofit(): Retrofit {
val retrofit = Retrofit.Builder()
.client(buildOkHttp(builder))
.baseUrl(buildUrl())
.addInterceptor(XXXInterceptor())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addCallAdapterFactory(CoroutineCallAdapterFactory.invoke())
.addConverterFactory(WireConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
return retrofit.build()
}
Retrofit.Builder 的 build 方法
public Retrofit build() {
if (baseUrl == null) {
throw new IllegalStateException("Base URL required.");
}
okhttp3.Call.Factory callFactory = this.callFactory;
// 网络请求实现类
if (callFactory == null) {
callFactory = new OkHttpClient();
}
// 请求适配器工厂类,并添加默认的请求适配器工厂类
List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
// 内容解析器工厂类
List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
callbackExecutor, validateEagerly);
}
Retrofit 的 create 方法
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, @Nullable Object[] args) {
// 对网络请求方法进行包装生成ServiceMethod
ServiceMethod<Object, Object> serviceMethod = loadServiceMethod(method);
// 生成网络请求对象
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
// 通过 adapt 方法进行网络请求
return serviceMethod.callAdapter.adapt(okHttpCall);
}
});
}
ServiceMethod 的 build 方法
ServiceMethod<?, ?> loadServiceMethod(Method method) {
ServiceMethod<?, ?> result = serviceMethodCache.get(method);
if (result != null) return result;
synchronized (serviceMethodCache) {
result = serviceMethodCache.get(method);
if (result == null) {
result = new ServiceMethod.Builder<>(this, method).build();
serviceMethodCache.put(method, result);
}
}
return result;
}
public ServiceMethod build() {
// 遍历工厂类,根据 Method 的返回值类型决定采用那个 Adapter,
// 如果是String、Int等则采用默认提供的 Adapter,如果是 Completable<T>,则采用RxjavaAdapter
callAdapter = createCallAdapter();
responseType = callAdapter.responseType();
// 遍历内容解析器工厂类,根据 responseType 来决定采用那个解析器,
// 比如Response继承了 Message,则 WireConverterFactory 会返回 WireResponseBodyConverter
responseConverter = createResponseConverter();
for (Annotation annotation : methodAnnotations) {
parseMethodAnnotation(annotation);
}
return new ServiceMethod<>(this);
}
这里假设我们采用了RxJava2CallAdapter请求适配器,直接看 adapt 实现,通过适配器模式,直接通过CallExecuteObservable封装了call.execute请求
public <R1> R adapt(Call<R1> call) {
Observable<SsResponse<R1>> responseObservable = isAsync
? new CallEnqueueObservable<>(call)
: new CallExecuteObservable<>(call);
Observable<?> observable;
if (isResult) {
observable = new ResultObservable<>(responseObservable);
} else if (isBody) {
observable = new BodyObservable<>(responseObservable);
} else {
observable = responseObservable;
}
if (scheduler != null) {
observable = observable.subscribeOn(scheduler);
}
if (isFlowable) {
return (R) observable.toFlowable(BackpressureStrategy.LATEST)
.retryWhen(new RetryWhenPublisherHandler(retryCount));
}
if (isSingle) {
return (R) observable.singleOrError()
.retryWhen(new RetryWhenPublisherHandler(retryCount));
}
if (isMaybe) {
return (R) observable.singleElement()
.retryWhen(new RetryWhenPublisherHandler(retryCount));
}
if (isCompletable) {
return (R) observable.ignoreElements()
.retryWhen(new RetryWhenPublisherHandler(retryCount));
}
return (R) RxJavaPlugins.onAssembly(observable)
.retryWhen(new RetryWhenHandler(retryCount));
}
OkHttpCall.execute -> OkHttpCall.parseResponse -> serviceMethod.toResponse
@Override public Response<T> execute() throws IOException {
okhttp3.Call call;
synchronized (this) {
if (executed) throw new IllegalStateException("Already executed.");
executed = true;
if (creationFailure != null) {
if (creationFailure instanceof IOException) {
throw (IOException) creationFailure;
} else {
throw (RuntimeException) creationFailure;
}
}
call = rawCall;
if (call == null) {
try {
call = rawCall = createRawCall();
} catch (IOException | RuntimeException e) {
creationFailure = e;
throw e;
}
}
}
// 最终调用 内容解析器 解析,然后该方法返回值返回给 网络适配器,并通过RxJava发射出去
return parseResponse(call.execute());
}
Interceptor 经典用法
Passport Sdk 会提供 TTTokenInterceptor,用于自动处理 request 和 response,用于从 response中提取鉴权信息并在 header 中添加身份鉴权信息