代理分为静态代理和动态代理,静态代理是在编译时就将接口、实现类、代理类一股脑儿全部手动完成,但如果我们需要很多的代理,每一个都这么手动的去创建实属浪费时间,而且会有大量的重复代码,此时我们就可以采用动态代理,动态代理可以在程序运行期间根据需要动态的创建代理类及其实例,来完成具体的功能。
Proxy.newProxyInstance()方法利用参数中的classLoader生成字节码文件并动态生成代理类
P
r
o
x
y
N
,
这
个
类
继
承
了
P
r
o
x
y
并
且
实
现
了
传
入
的
一
组
接
口
,
循
环
遍
历
传
入
接
口
中
的
每
一
个
方
法
,
将
方
法
设
置
到
ProxyN,这个类继承了Proxy并且实现了传入的一组接口,循环遍历传入接口中的每一个方法,将方法设置到
ProxyN,这个类继承了Proxy并且实现了传入的一组接口,循环遍历传入接口中的每一个方法,将方法设置到ProxyN中,父类Proxy中有InvocationHandler h属性,利用反射获得传入接口中的方法method,将method作为参数传入h中,调用h的invoke方法利用反射完成代理。
Proxy 类是它的父类,这个规则适用于所有由 Proxy 创建的动态代理类。(也算是java动态代理的一处缺陷,java不支持多继承,所以无法实现对class的动态代理,只能对于Interface的代理)而且该类还实现了其所代理的一组接口,这就是为什么它能够被安全地类型转换到其所代理的某接口的根本原因。
传入一组接口的原因,1、面向接口编程,一种规范;2、java不支持多继承,如果一个类实现了一组接口,对其进行代理时,不同接口的不同方法都会得到增强。
一个典型的动态代理创建对象过程可分为以下四个步骤:
1、通过实现InvocationHandler接口创建自己的调用处理器 IvocationHandler handler = new InvocationHandlerImpl(…);
2、通过为Proxy类指定ClassLoader对象和一组interface创建动态代理类
Class clazz = Proxy.getProxyClass(classLoader,new Class[]{…});
3、通过反射机制获取动态代理类的构造函数,其参数类型是调用处理器接口类型
Constructor constructor = clazz.getConstructor(new Class[]{InvocationHandler.class});
4、通过构造函数创建代理类实例,此时需将调用处理器对象作为参数被传入
Interface Proxy = (Interface)constructor.newInstance(new Object[] (handler));
为了简化对象创建过程,Proxy类中的newInstance方法封装了2~4,只需两步即可完成代理对象的创建。
java.lang.reflect.Proxy——Java动态代理深度解析
最新推荐文章于 2023-12-28 12:40:54 发布