Retrofit源码学习之动态代理
来源:互联网 发布:大学的意义知乎 编辑:程序博客网 时间:2024/04/30 07:07
我们已经知道retrofit的主要作用是把一个接口解析包装成http的请求,由OKhttp发送。用到的技术就是动态代理。动态代理的作用就是当你要调用某个Class的方法前或后,插入你想要执行的代码。接下来我们看一下如何实现动态代理。
一、定义接口:
public interface UserListener { String getName(); int getAge();}
二、创建该接口的实现类
public class User implements UserListener { @Override public String getName() { return "哈哈哈"; } @Override public int getAge() { return 18; }}
三、创建动态代理类并实现InvocationHandler接口,该接口只包含一个方法,之后再讲解它
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
动态代理类:
public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target){ this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if(method.getName().equals("getName")){ String result = (String) method.invoke(target,args); return result+"嘿嘿嘿"; }else { int age = (int) method.invoke(target,args); return age+10; } }}
四、使用动态代理类:
UserListener user = new User(); MyInvocationHandler handler = new MyInvocationHandler(user); UserListener proxy = (UserListener) Proxy.newProxyInstance(user.getClass().getClassLoader(),user.getClass().getInterfaces(),handler); Log.d("proxy",proxy.getName()); Log.d("proxy",proxy.getAge()+"");
结果:
03-11 13:05:22.631 30332-30332/com.yjs.okhttp D/proxy: 哈哈哈嘿嘿嘿03-11 13:05:22.641 30332-30332/com.yjs.okhttp D/proxy: 28
解析
首先看一下InvocationHandler中的方法,
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
Object proxy:指代我们所代理的那个真实对象
Method method:指代的是我们所要调用真实对象的某个方法的Method对象
Object[] args:指代的是调用真实对象某个方法时接受的参数
接下来再看一下Proxy类中的newProxyInstance方法:
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
ClassLoader loader:定义了由哪个ClassLoader对象来对生成的代理对象进行加载
Class<?>[] interfaces:一个Interface对象的数组,表示的是我将要给我需要代理的对象提供一组什么接口,如果我提供了一组接口给它,那么这个代理对象就宣称实现了该接口(多态),这样我就能调用这组接口中的方法了
InvocationHandler h:一个InvocationHandler对象,表示的是当我这个动态代理对象在调用方法的时候,会关联到哪一个InvocationHandler对象上
最后看一下Retrofit中的创建方法:
ApiStores apiStores = ApiClient.retrofit().create(ApiStores.class);
public <T> T create(final Class<T> service) { Utils.validateServiceInterface(service); if (validateEagerly) { eagerlyValidateMethods(service); } return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service }, new InvocationHandler() { private final Platform platform = Platform.get(); @Override public Object invoke(Object proxy, Method method, Object... args) throws Throwable { // If the method is a method from Object then defer to normal invocation. if (method.getDeclaringClass() == Object.class) { return method.invoke(this, args); } if (platform.isDefaultMethod(method)) { return platform.invokeDefaultMethod(method, service, proxy, args); } ServiceMethod serviceMethod = loadServiceMethod(method); OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args); return serviceMethod.callAdapter.adapt(okHttpCall); } }); }
当我们把包含网络请求接口的类传入到Retrofit的create方法后,就会利用动态代理模式,将接口解析包装成ServiceMethod,再转化成OkHttpCall供OKhttp调用。
- Retrofit源码学习之动态代理
- Retrofit源码解析-动态代理
- Retrofit源码解析-动态代理
- Spring源码学习之动态代理
- Retrofit的动态代理
- jdk动态代理源码学习
- JDK动态代理源码学习
- Retrofit(okhttp)的动态代理
- JAVA学习之动态代理
- JAVA学习之动态代理
- JAVA学习之动态代理
- Spring学习之动态代理
- 学习Spring之动态代理
- Retrofit 1.9源码学习
- 动态代理源码解析之JDK
- JDK动态代理源码分析之二
- Retrofit源码学习笔记(1)一Retrofit
- [Android] Retrofit 源码分析之 Retrofit 对象
- tmux配置
- android_audio_system框架
- “输入三个字符后,按个字符的ASCII码从小到大的顺序输出这三个字符”的做法
- 我的测试驱动实践
- 段错误总结
- Retrofit源码学习之动态代理
- 关于MaterialDesign 几种控件的介绍
- 中断法定时
- 2016年上海SODA开放数据大赛进入复赛作品《安全橙子》网页源码(利用百度echart框架热力图展示城市安全信息)
- 重构:引入NULL对象
- mat相关函数
- 2017-03-11
- Effective java笔记-对于所有对象都通用的方法
- 递归生成格雷码