# Retrofit 2.0 源码分析

有很多关于Retrofit源码的分析,但是我总觉得分析的还不够透彻。

环境

AndroidStudio 2.0

准备

gradle:

ompile 'com.squareup.retrofit2:retrofit:2.0.0-beta4'
compile 'com.squareup.retrofit2:converter-gson:2.0.0-beta4'
compile 'com.squareup.okhttp3:okhttp:3.0.1'
compile 'com.google.code.gson:gson:2.3'

知识点

  • retrofit的低耦合
  • retrofit的动态代理

retrofit的低耦合

当我们用retrofit的时候都用到下面的代码构建retrofit实例:

OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .readTimeout(7676, TimeUnit.MILLISECONDS)
            .connectTimeout(7676, TimeUnit.MILLISECONDS)
            .addInterceptor(new FakeInterceptor())
            .build();

retrofit = new Retrofit.Builder()
            .baseUrl(ENDPOINT)
            .addConverterFactory(GsonConverterFactory.create())
            .client(okHttpClient)
            .build();

如果你用到rxjava,因为要将Service返回数据改成Obervable的问题需要这么用:

retrofit = new Retrofit.Builder()
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())//这个是为了RxJava
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl(ENDPOINT)
        .client(client)
        .build(); 

总结Retrofit主要有以下几种数据创建工厂.

  • CallAdapterFactory 创建对service的返回值做除了默认Call的其他数据类型的实例的工厂
  • ConverterFactory 创建对请求获得到的数据进行转换的实例的工厂
  • CallFactory 创建http请求客户端的实例的工厂(retrofit2.0只允许要求使用okHttpClient)

为什么说retrofit低耦合

如图:


Builder build method.jpg

retrofit构建采用建造者模式,上图build method 中将框架使用者add的数据和框架默认使用到CallAdapterFactory,ConverterFactory, CallFactory三种数据进行整合(add),然后创建出retrofit实例返回。

框架使用者通过链式传入定制数据类型,然后通过build进行整合,友好的将框架开发者和使用者进行解耦。

retrofit 2.0 http请求客户端必须使用okhttp,所以如果你要定制http请求客户端,也只能使用OkHttpClient。看下retrofit下的build方法中:

if (callFactory == null) {
    callFactory = new OkHttpClient();
  }

retrofit的动态代理

当构建好Retrofit实例后,我们会使用create方法,传入对应的Service.class,构建出Http请求。

public  <T> T createService(Class<T> clz){
    return retrofit.create(clz);
}
//Service
public interface RestApi {
    @GET("/")
    Call<Teacher> getTeacherById(@Query("id")  String id);
}

retrofit只需要创建好interface,然后就能轻易的做到数据请求,就是因为用到了Java 5 的动态代理,核心方法就是create方法。

retrofit create build.png

动态代理:就是代码的自动生成,定义了一个interface后,通过动态代理将接口转换为拥有具体代码的类。即用代码动态生成想要的类。

Java 5的动态代理引入InvocationHandler,在invoke方法中,可以直接获取正在调用对应Method对象。

所以create方法正常执行下面这条语句:

 return loadMethodHandler(method).invoke(args);

这里的MethodHandler是做了缓存的:

loadMethodHandler.jpg

然后我们再来看MethodHandler.invoke方法:

Screen Shot 2016-04-17 at 23.39.49.png

这里我们可以看出内部请求返回的数据类型是OkHttpCall,然后通过CallAdapter进行数据转换返回。

总结

  • retrofit 2.0框架中代码风格值得我们去学习,可扩展性和解耦方式做的都非常好。

  • 动态代理主要是用来做方法的增强,还有一个有趣的作用是可以用作远程调用,比如现在有Java接口,这个接口的实现部署在其它服务器上,在编写客户端代码的时候,没办法直接调用接口方法,因为接口是不能直接生成对象的,这个时候就可以考虑代理模式(动态代理)了,通过 Proxy.newProxyInstance代理一个该接口对应的InvocationHandler对象,然后在InvocationHandler的invoke方法内封装通讯细节就可以了。具体的应用,最经典的当然是Java标准库的RMI,其它比如hessian,各种webservice框架中的远程调用,大致都是这么实现的。

  • 如果你想详细了解动态代理参考:
    https://www.zhihu.com/question/20794107
    http://tutorials.jenkov.com/java-reflection/dynamic-proxies.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容