代理模式
代理模式是java常见设计模式中的一种,他的主要作用是提供一个代理给外部访问,真实执行的对象通过代理间距去执行。比如:
1 | fun main() { |
该模式主要是应用在一个类对另外一个类的代理操作,他的缺点是当有多个类(比较多不同类,不同层级等)需要代理的时候,需要编写较多代理类,这时候我们就可以引入动态代理了。
动态代理
他是主要原理是利用反射机制在运行时创建代理类。比如上面的例子,我们使用动态代理的写法是:
1 |
|
为什么类可以动态生成,参考深入理解Java动态代理,>类的加载阶段分为加载,验证,准备,解析,初始化,其中加载阶段需要完成下面三件事情:
a. 通过一个类的权限定名来获取定义该类的二进制字节流
b. 将字节流所代表的的静态存储接口转化为方法区的运行时数据结构
在内存中生成一个代表这个类的java.lang.class对象,作为方法去这个类的各种数据访问入口。
由于虚拟机规范对这三点要求并不具体,关于第一点有很多的途径:包括zip包获取,网络获取,运行时计算生成,其他文件生成,数据库获取等。
本文就是讨论运行时生成这种方式,主要是关乎两个类,Proxy和InvocationHandler。我们从例子看到Proxy主要作用是构造反射对象,InvocationHandler是处理对象的方法调用。我们就看下这两个类,首先是InvocationHandler,他是一个接口,定义了一个方法invoke
1 | //proxy为代理对象,method是需要执行的方法,args是的参数 |
通过这个方法,可以让代理对象调用到真实对象的对应方法。
Proxy类提供一个方法
1 | //loader用于定义动态代理类,interface是动态代理类需要实现的接口,必须是接口,而且数量不能超出65535,而且不能有相互继承,h就是我们的代理类调用正式对象的方法。 |
通过调用这个方法就可以生成一个代理类实现动态代理模式了。
动态代理的原理
他的主要关键点就是生成代理类,我们看下他的源码(注意:Android与纯Java的生成代理类的方式略有不同,这里使用的Android的),可以参考视频:破解Retrofit
1 | public static Object newProxyInstance(ClassLoader loader, |
1 | //缓存并生成代理类的WeakCache |
然后我们看WeakCache的get方法
1 | public V get(K key, P parameter) { |
可以看到最终是由我们传入WeakCache构造函数的ProxyClassFactory类负责生成的,他的apply方法
1 | @Override |