独特的架构方式,Retrofit源码简析。

retrofit2.0

2016/07/21
上海
Read the fucking source code。

    Retrofit,Type-safe HTTP client for Android and Java 。
    GitHub:http://square.github.io/retrofit

开始之前,先回想下一个网络请求的基本姿势(默认框架搭建完成):
1,生成请求参数,确定接口
2,利用NetWork模块,发送到指定API
3,响应成功,反序列
4,响应失败,做某些处理
5,线程调度,结果交给前台

Retrofit作为NetWork框架,也不例外。
1,以接口+注解的形式,生成请求参数,确定接口
2,利用CallFactory生成NetWork模块,发送到指定API
3,响应成功,利用ConverterFactory反序列
4,响应失败,做某些处理
5,请求结果经过CallAdapterFactory包装
6,CallAdapterFactory包装包装后,线程调度,结果交给前台

目录:
1,我们配置Retrofit时,到底发生了什么?
2,Retrofit.create(final Class service)都做了什么?
3,ServiceMethod 是什么?
4,OkHttpCall 是什么?
5,serviceMethod.callAdapter.adapt(okHttpCall)是什么鬼?
6,CallFactory、okHttpCall、CallAdapter之间的关系?


问题一:我们配置Retrofit时,到底发生了什么?


//Retrofit构造器
new Retrofit.Builder()        
//配置服务器
.baseUrl(UrlHelp.SERVER_IP)                                     
//反序列工具生成器
.addConverterFactory(XmlToJsonConverterFactory.create())
.//结果包装工具生成器(不大好描述..)        
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())       
//NetWork工具生成器
.callFactory(HttpClient())        
//线程调度
.callbackExecutor()            
.build();

** 配置:**
ConverterFactory 反序列工具生成器
CallAdapterFactory 结果包装工具生成器 默认为ExecutorCallAdapterFactory
okhttp3.Call.Factory NetWork工具生成器 默认为OkHttpClient
CallbackExecutor 线程调度

配置的是Retrofit的功能模块,Retrofit将网络请求流程中的各个关节(是的,关节)部位打断,使各个模块之间相关性降到最低,再通过“配置”的方式开放出来,应对复杂的使用环境。

Retrofit(
  okhttp3.Call.Factory callFactory, 
  HttpUrl baseUrl,
  List converterFactories, 
  List adapterFactories,    
  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;
}

.build()方法new Retrofit()实例并返回,new Retrofit()时传入配置信息。


问题二:Retrofit.create(final Class service)都做了什么?


mRetrofit.create(RetorfitInterfaces.UserInfoServer.class)        
.sendPost(userId)        
.enqueue(call);

create(final Class service),传入自定义接口,返回接口实例。
在外部使用中,这是最直接的感受,实际上返回的是代理对象。

//仅摘取核心部分
public  T create(final Class service) {      
......
  return (T) Proxy.newProxyInstance(
          ...    
          new InvocationHandler() {        
            .....
            @Override 
            public Object invoke(Object proxy, Method method, Object... args) throws Throwable {
                ......
                //加载ServiceMethod
                ServiceMethod serviceMethod = loadServiceMethod(method);
                //加载OkHttpCall 
                OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
                //调用callAdapter.adapt(okHttpCall)
                return serviceMethod.callAdapter.adapt(okHttpCall);
        }
      });
}

这部分源码写的很直观,简单来说当调用接口中的方法时,都会运行InvocationHandlerinvoke()方法。

重点就在invoke(Object proxy, Method method, Object... args)方法中的三句代码:

ServiceMethod serviceMethod = loadServiceMethod(method);
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
return serviceMethod.callAdapter.adapt(okHttpCall);


问题三:ServiceMethod 是什么?



(以下省略适配、优化等细节代码)

//调用Retrofit.loadServiceMethod(method);加载ServiceMethod;
serviceMethod = loadServiceMethod(method);
ServiceMethod loadServiceMethod(Method method) {
  ServiceMethod result;
   ....
      //通过 ServiceMethod.Builder构造器创建实例
      result = new ServiceMethod.Builder(this, method).build();
   ....
  return result;
}
public Builder(Retrofit retrofit, Method method) {
//持有了retrofit实例,retrofit持有前面说到的各配置组件,
//也就是说ServiceMethod相当于持有各配置组件,
//变相的将四大组件组装在了一起。
  this.retrofit = retrofit;

  ..注解解析相关...
}
public ServiceMethod build() {
.....

//创建CallAdapter实例,createCallAdapter()是ServiceMethod.Builder的私有方法,在此简写
  callAdapter = createCallAdapter(){
     ....
     //调用了Retrofit实例的CallAdapter();CallAdapter()是Retrofit的公共方法,在此简写
     return retrofit.callAdapter(returnType, annotations){
         ...
               //Retrofit利用配置中的CallAdapterFactory获取CallAdapter实例
               return CallAdapterFactory.get();
           };
   };

......

  //创建responseConverter 反序列工具实例,createResponseConverter()是ServiceMethod.Builder的私有方法,在此简写
  responseConverter = createResponseConverter(){
            ....
      //调用Retrofit实例的responseBodyConverter()方法
      return retrofit.responseBodyConverter(responseType, annotations){
                    ....
                   //利用converterFactory工厂创建反序列工具
                    return converterFactory.responseBodyConverter();
             }
   };

...注解相关...  

  //调用ServiceMethod的构造函数ServiceMethod(Builder builder);创建实例
   return new ServiceMethod<>(this);
}

//ServiceMethod.Builder构造器(注意还不是ServiceMethod)持有了Retrofit实例,CallAdapter实例,responseConverter 反序列工具实例。

//ServiceMethod构建方法,参数是构造器
ServiceMethod(Builder builder) {
          this.callFactory = builder.retrofit.callFactory();//持有CallFactory实例
          this.callAdapter = builder.callAdapter;            //持有CallAdapter实例
          this.baseUrl = builder.retrofit.baseUrl();          //持有BaseUrl
          this.responseConverter = builder.responseConverter;//持有反序列工具
          ....注解相关
}

至此,ServiceMethod实例创建完毕,ServiceMethod变相的将各模块组装在一起。


问题四:OkHttpCall是什么?



先说两个概念:

interface okhttp3.Call{
       enqueue(Callback responseCallback);
       execute();
       request();
       isExecuted();
       isCanceled();
       cancel();
}    

interface retrofit2.Call{
       同上;
       clone();
}        

1,retrofit2.Call与okhttp3.Call区别就是多了个clone方法,retrofit2.Call需要clone,才能再次使用。
2,OkHttpCall 实现了retrofit2.Call。
3,CallFactory创建的是okhttp3.Call实例,OkHttpClient实现了okhttp3.Call。
WTF??看代码。

(以下省略适配、优化等细节代码)

//直接调用构造方法
OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
OkHttpCall(ServiceMethod serviceMethod, Object[] args) {
       this.serviceMethod = serviceMethod;  //持有了ServiceMethod实例
       this.args = args;//注解相关
}

OkHttpCall持有serviceMethod实例,就这样。但OkHttpCall 实现了retrofit2.Call,有必要看一下enqueue(Callback responseCallback);execute();

//外部传入callBack,结果回调
enqueue(final retrofit2.Callback outCallback){
        //Retrofit NetWork模块实际使用的还是okhttp3.Call,retrofit2.Call只是对外放出的包装
        okhttp3.Call call = createRawCall(){
                //Retrofit 默认callFactory为OkHttpClient
                return serviceMethod.callFactory.newCall(request);
        };
        //利用okhttp3.Call发送请求,并传入新的CallBack();
        call.enqueue(
                new okhttp3.Callback() {
                        //成功
                        onResponse(okhttp3.Response rawResponse){
                            //parseResponse(rawResponse)是将请求结果反序列,内部调用ServiceMethod中的responseConverter,也就是配置里的反序列化工具生成JavaBean。
                            rawResponse = parseResponse(rawResponse)
                            //将反序列化后的JavaBean传给前台
                            outCallback.onResponse(rawResponse);
                        }
                        //失败
                        onFailure(Throwable e){
                            //将错误信息传给前台
                            outCallback.onFailure(e);
                        }
                }
        )
}
execute(){

        ...与enqueue大致相同, 也是利用CallFactory生成okhttp3.Call,调用okhttp3.Call.execute()

}

so:

1,OkHttpCall实现Retrofit.Call接口
2,CallFactory生成的Call对象为Okhttp3.Call接口
3,OkHttpCall持有CallFactory生成的Call对象
4,OkHttpCall在enqueue,execute方法中实际调用的是CallFactory生成的Call对象发送请求,OkHttpCall本身并没有NetWork的功能
5,所以,OkHttpCall只是适配器,或者说包装器,外部使用Retrofit.Call,Retrofit.Call内部使用Okhttp3.Call,Retrofit.Call与Okhttp3.Call之间,由OkHttpCall调度
6,OkHttpCall实现Retrofit.Call接口,与外部来说,无需关心NetWork到底是如何发送的


问题五:

serviceMethod.callAdapter.adapt(okHttpCall)是?



先回头撸一下

        mRetrofit
        //返回代理对象
        .create(RetorfitInterfaces.UserInfoServer.class)
        //serviceMethod.callAdapter.adapt(okHttpCall)返回retrofit2.Call对象
        .sendPost(userId)
        //调用返回的retrofit2.Call的enqueue方法
        .enqueue(call);

没毛病。

serviceMethod.callAdapter由Retrofit.CallAdapterFactory创建(上面源码有提到)。 而CallAdapterFactory可由外部配置,默认ExecutorCallAdapterFactory。

(以下省略适配、优化等细节代码)

//默认ExecutorCallAdapterFactory.adapt,创建返回了ExecutorCallbackCall实例
@Override public  Call adapt(Call call) {
        //call就是okHttpCall
       return new ExecutorCallbackCall<>(callbackExecutor, call);
}

//看看ExecutorCallbackCall又是什么,一个 Retrofit2.Call实现类,
class ExecutorCallbackCallimplements Retrofit2.Call{

        //构造函数,callbackExecutor配置中的线程池,delegate就是okHttpCall
        ExecutorCallbackCall(Executor callbackExecutor, retrofit2.Call delegate) {                this.callbackExecutor = callbackExecutor;                this.delegate = delegate;        }
        
         //Retrofit2.Call接口中的方法,发送异步请求,参数outCallBack是外部传入的回调接口
         enqueue(final Callback outCallback){
                //利用delegate,其实就是okHttpCall发送请求,又是包装new Callback()
                delegate.enqueue(new Callback() {
                    //成功
                     onResponse(Call call, final Response response) {
                            //线程调度
                             callbackExecutor.execute(new Runnable() {
                                    public void run() {
                                    //传给前台
                                      outCallBack.onResponse(
                                              ExecutorCallbackCall.this, response
                                      );
                                    }
                              }
                          }
                    //失败
                      onFailure(Call call, final Throwable t){
                            //线程调度
                            callbackExecutor.execute(new Runnable() {
                                public void run() {
                                    outCallBack.onFailure(ExecutorCallbackCall.this, t);
                                }
                            });
                      }
            );
        }
         // ****Retrofit2.Call接口中的方法,**发送同步请求**
        Response execute(){
                    //delegate 就是okHttpCall
                     return delegate.execute();
        }
}

1,serviceMethod.callAdapter.adapt(okHttpCall)返回Retrofit2.Call实例,默认ExecutorCallbackCall
2,ExecutorCallbackCall实例中持有okHttpCall的实例
3,ExecutorCallbackCall实例中的enqueue,execute方法,方法中实际操作的还是OkHttpCall对应的方法。
4,ExecutorCallbackCall将请求结果通过制定线程(配置中的CallbackExecutor)发送到前台


问题六:CallFactory、okHttpCall、CallAdapter之间的关系?



从上向下的包装关系,,类似装饰模式:
** 外部调用**
** CallAdapterFactory.CallAdapter.Retrofit.Call**
** 包装**
okHttpCall.Retrofit.Call
** 包装**
CallFactory.okhttp3.Call

                      外部调用                                 
|---------------------------------------------------|
|              CallAdapter.Retrofit.Call            |
|     |---------------------------------------|     |
|     |        okHttpCall.Retrofit.Call       |     |
|     |     -----------------------------     |     |
|     |     |  CallFactory.okhttp3.Call |     |     |
|     |     -----------------------------     |     |
|     |                                       |     |
|     |---------------------------------------|     |
|                                                   |
|---------------------------------------------------|

CallFactory.okhttp3.Call面向发送请求,不关心结果处理
CallAdapterFactory.CallAdapter.Retrofit.Call面向返回结果,不关心发送
OkHttpCall.Retrofit.Call作为中间件,将两者联系起来
**外部实际调用的是CallAdapter生成的Retrofit.Call **

你可能感兴趣的:(独特的架构方式,Retrofit源码简析。)