小手动一动,点赞转发加关注。微信搜索【大前端杂货铺】公众号关注大前端老司机带您遨游大前端知识的海洋。关注 Github github.com/big-fronten… 还有大前端代码实践哦。
Retrofit 名词解释
Retrofit是由Square公司出品,基于OkHttp做的一层Restful API封装,关于什么是Restful API,请参考这一篇文章理解RESTful架构,闲话不多说,进入主题
Adapter:通过抽象工程模式创建Adapter,然后将Call适配成其他类型。eg. Call ---> RxJava
Converter:转换response的流数据为其他数据格式。eg. response data stream ---> json
Retrofit 设计原理
对于开发者来说主要使用注解的形式为自己的网络api声明,后面的发送请求的事情就自动交给了Retrofit,彻底的解放双手。那么Retrofit是如何实现这么一项代理发送请求的功能,让我们往下看。
Retrofit库通过动态代理生成具体的实现类,每一个java interface类的方法声明信息都会被ServiceMethod类解析。
ServiceMethod/HttpServiceMethod
abstract class ServiceMethod<T> {
static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
...
return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
}
abstract @Nullable T invoke(Object[] args);
}
abstract class HttpServiceMethod<ResponseT, ReturnT> extends ServiceMethod<ReturnT> {
...
static final class CallAdapted<ResponseT, ReturnT> extends HttpServiceMethod<ResponseT, ReturnT> {
private final CallAdapter<ResponseT, ReturnT> callAdapter;
CallAdapted(RequestFactory requestFactory, okhttp3.Call.Factory callFactory,
Converter<ResponseBody, ResponseT> responseConverter,
CallAdapter<ResponseT, ReturnT> callAdapter) {
super(requestFactory, callFactory, responseConverter);
this.callAdapter = callAdapter;
}
@Override protected ReturnT adapt(Call<ResponseT> call, Object[] args) {
return callAdapter.adapt(call);
}
}
}
ServiceMethod类是一个抽象类,其parseAnnotations方法会解析http协议相关的注解信息然后生成RequestFactory,HttpServiceMethod的parseAnnotations会构建CallAdapted并且注入RequestFactory对象、CallAdapter对象、Converter对象。
HttpServiceMethod
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
Retrofit retrofit, Method method, RequestFactory requestFactory) {
...
Annotation[] annotations = method.getAnnotations();
Type adapterType;
if (isKotlinSuspendFunction) {
...
} else {
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;
if (!isKotlinSuspendFunction) {
return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
} else if (continuationWantsResponse) {
...
} else {
...
}
}
@Override final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
return adapt(call, args);
}
上面就是HttpServiceMethod构建CallAdapted的parseAnnotations,解析完注解提供的信息并构建ServiceMethod对象,然后会调用HttpServiceMethod的invoke方法发送请求。Call对象能被适配成各种对象,比如RxJava中的观察者对象,Rxjava的观察者对象通过链式调用各种操作符从而完成任务处理。
Retrofit 改造
OkhttpCall实现了Retrofit Call且封装了Okhttp的网络请求,如果我们使用了UrlConnection,那么也可以封装成UrlConnectionCall,或者对于现在的很多公司都会基于tcp自定义协议,比如阿里mtop,携程sotp,也可以封装其Call。有兴趣的可以阅读我改造的这个项目super-retrofit,就是实现这样一种逻辑。
@Override
final @Nullable ReturnT invoke(Object[] args) {
Call<ResponseT> call = callFactory.newCall(requestFactory,args,responseConverter);
return adapt(call, args);
}
通过外部提供的CallFactory,构建了自己的Call,然后在自己的Call类中实现Retrofit Call提供的抽象接口。
小手动一动,点赞转发加关注。微信搜索【大前端杂货铺】公众号关注大前端老司机带您遨游大前端知识的海洋。关注 Github github.com/big-fronten… 还有大前端代码实践哦。