Retrofit是如何解析注解以及装配参数的呢?
serviceMethodCached是线程安全的。它用于缓存我们创建的ServiceMethod实例,由于我们需要频繁的去请求定义的接口中的方法,当有ServiceMethod实例的缓存时,就不需要频繁创建了。
下图的Builder将
上图中的paresHttpMethodAndPath方法的注解进行解析,是否有HttpMethod:即Get或者POST。是否有body,是否有@Query注解的参数,请求路径中是否有参数等等,有就会进行解析。下图的parseParameter方法便开始对请求方法中的参数进行解析。
Retrofit通过我们调用create方法时传递的接口,通过Java内置的动态代理对象Proxy的newProxyInstance方法,为我们动态生成Proxy代理类实例,该实例是Proxy类型实例,Java的动态代理只能为接口创建代理类,不能为抽象类或其他类生成代理类,否则会报错。
Java8中interface也能定义deafault方法。
Retrofit.create()就是通过Java的动态代理将我们自定义实现的请求Interface的方法先转给了InvocationHandler的invoke(),再转嫁给loadServiceMethod实例的invoke(),该invoke方法生成了一个okhttpCall实例。
Gson对象实例化流程
动态代理JDK原生实现与cglib实现的对比
记一个能记笔记的笔记哦
学习到了很多:
1. 阅读源码的方式
① 站在使用者的角度,从使用到的代码,一步步深入,直到具体的实现,如Retrofit.create(),返回得到接口的实体是动态代理得到的;如IApiService的每个方法调用,返回得到Call/Observable,通过解析方法上的注解,得到HttpServiceMethod$CallAdapted,将OkHttpCall转换得到相应的类型,如Call,调用Call.execute(),内部调用OkHttpCall.execute(),通过OkHttpClient执行真正的网络请求;又如CallAdapter是如何将Call转换成需要的类型的。
② 再找一些我们熟悉的知识点进一步了解原理,如解析注解的过程,如OkHttpCall的内部实现方式,如反序列化的实现。
③ 总结其中使用到的设计模式,查看已经熟悉的设计模式,进一步了解原理,查看不熟悉的设计模式,了解库的实现者是如何利用这种设计模式的。总的来说,还是以我们熟悉的方式去查看源码。
④ 根据需求,可以总结库的优劣势,需要学习到的点,可能会在日常开发中使用到的点,甚至是对库的建议。
2. 某些知识点的了解
① 注解的使用场景。在Retrofit中,注解主要用于业务逻辑的处理。另外还有在Room/Dagger中,注解用于在编译期生成代码,在编译器生成字节码。
② kotlin的原理,编译时修改函数签名,在函数中参数列表末尾添加一个Continutation参数(实际上是一个回调接口)。
③ Gson的实现原理。使用构造器/Unsafe,创建实体或分配实体需要的内存空间,读取json数据,解析类上的注解。
④ 反射、泛型的浅层了解。
另外还有未完全掌握的知识点:
泛型的深入理解,如wildcard,类型擦除所带来的问题与解决方案,特别是运行时。理解signature
Unsafe的使用与原理
反射的深入了解
用反射的方式修改反射本身
类中声明一个属性:private static final int a =1,这个 a 可以通过反射修改吗?
不能,运行时会抛出 IllegalAccessException 异常
对象中声明一个属性:private final int a =1,这个 a 可以通过反射修改吗?
不能,源码编译时会将 a 编译为一个编译期常量,把这个字段被使用的地方都替换为直接的字面量
如何动态修改 Retrofit 的 BaseUrl?
* 持有 HttpUrl 的引用
* 通过反射修改 HttpUrl 中的 Schema、Host、Port 等内部字段的值
自定义一下maven仓库
0.0啊呀呀
代理的其他实现方案:Cglib
eg. Spring中使用的就是Cglib
接口的实现类是从哪里来的?
create方法中通过java内置的动态代理实现的。将接口中的所有方法转给了InvocationHandler的invoke方法,并返回一个loadServiceMethod(是一个ServiceMethod)方法。由它发起网络请求。
Gson反序列化过程
了解Retrofit的内部实现原理
5-4 代理模式
适配器模式
Builder模式
抽象工厂模式
Gson对象实例化流程
静态代理3
动态代理JDK原生实现与cglib实现的对比