retrofit相关文章虽然对,作为学习笔记使用,有问题希望能够尽情提出,共同交流
蒋八九
概述
retrofit说白了就是动态代理的原理,这篇文章源码分析不对,要是了解动态的代理的话,那么retrofit就没什么难度的了
注解的基本知识
- @Retention – 定义该注解的生命周期
● RetentionPolicy.SOURCE : 在编译阶段丢弃。这些注解在编译结束之后就不再有任何意义,所以它们不会写入字节码。@Override, @SuppressWarnings都属于这类注解。
● RetentionPolicy.CLASS : 在类加载的时候丢弃。在字节码文件的处理中有用。注解默认使用这种方式
● RetentionPolicy.RUNTIME : 始终不会丢弃,运行期也保留该注解,因此可以使用反射机制读取该注解的信息。我们自定义的注解通常使用这种方式。 - Target – 表示该注解用于什么地方。默认值为任何元素,表示该注解用于什么地方。可用的ElementType 参数包括
● ElementType.CONSTRUCTOR: 用于描述构造器
● ElementType.FIELD: 成员变量、对象、属性(包括enum实例)
● ElementType.LOCAL_VARIABLE: 用于描述局部变量
● ElementType.METHOD: 用于描述方法
● ElementType.PACKAGE: 用于描述包
● ElementType.PARAMETER: 用于描述参数
● ElementType.TYPE: 用于描述类、接口(包括注解类型) 或enum声明
● ElementType.ANNOTATION_TYPE - @Documented – 一个简单的Annotations 标记注解,表示是否将注解信息添加在java 文档中。
- @Inherited – 定义该注释和子类的关系
@Inherited 元注解是一个标记注解,@Inherited 阐述了某个被标注的类型是被继承的。如果一个使用了 @Inherited 修饰的annotation 类型被用于一个class,则这个annotation 将被用于该class 的子类。
设计模式:
建造模式、动态代理模式
主要实现方法:
一、首先通过build构造器构造一个Retrofit对象,也就将url地址、converterFactory(gson解析器)、rxjava适配工厂、okhttpClient对象,都封装到Retrofit中去。
Retrofit mRetrofit = new Retrofit.Builder().baseUrl(params.url)
.addConverterFactory(factory)
.addCallAdapterFactory(adapterFactory)
.client(mOkHttpClient)
.callFactory(params.callFactory).build();
二、然后调用mRetrofit.create()方法,通过动态代理的方式,得到请求接口的代理类。当调用这个类中的请求方法时就会触发这个代理类的invok方法进行网络请求,并最终返回请求结果。
1、通过create方法传入class字节码,通过反射机制获取自定义接口类实例;
RetrofitApi retrofitApi = retrofit.create(RetrofitApi.class);
public <T> T create(final Class<T> service) {
2、限定自定义类必须是一个无继承的接口类,不然抛异常
Utils.validateServiceInterface(service);
..........
3、使用jdk的动态代理机制,实现InvocationHandler的匿名内部类
return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
new InvocationHandler() { //实现InvocationHandler匿名内部类
..........
4、当调用retrofitApi中的方法的时候,通过动态代理机制间接的触发invoke方法。
@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
throws Throwable {
5、这里Object的方法指的是toString、equals、hashcode等方法
if (method.getDeclaringClass() == Object.class) {
return method.invoke(this, args);
}
if (platform.isDefaultMethod(method)) {
return platform.invokeDefaultMethod(method, service, proxy, args);
}
6、将Method方法中的注解、类型等信息解析成ServiceMethod对象,然后存放到ServiceMethodCache缓存HashMap中,这是Retrofit类中的ConcurrentHashmap集合,以Method为key,ServiceMethod为值存放。
ServiceMethod<Object, Object> serviceMethod =
(ServiceMethod<Object, Object>) loadServiceMethod(method);
7、将缓存请求方法的ServiceMethod对象和请求入参args一起包装到OkHttpCall对象中。
OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
8、最后根据一系列的判断,将okHttpCall装饰成最终的特定的Observable类型,然后返回。所以这里的adapt其实就相当于一个适配器模式。
return serviceMethod.adapt(okHttpCall);
}
});
}