最近在学习Java,学习到了一个新的Java特性——代理(Proxy)。代理可以为其它对象实现一种新的控制访问方式,这是Java SE1.3新加的特性。
目的
假如我们希望在运行时创建一个实现了一组给定接口的新类,我们就可以使用代理实现。
模式
代理类可以运行时创建全新的类,这个代理类能够实现指定的接口:
- 指定接口所需要的全部方法
- Object类中的全部方法
这个模式首先要让代理类和目标类实现相同的接口,然后客户端在通过代理类调用目标类的时候,代理类会将所有方法调用分派到目标对象上反射执行。分派过程中则可以在前后增加一些想要的功能。
步骤
- 通过实现InvocationHandler接口来自定义自己的handler,该接口有一个invoke的方法;
- 使用Proxy类的newProxyInstance创建一个代理对象,并将handler传入该对象;
- 通过代理对象调用目标方法;
原理
首先来看一个实现例子,这个程序会打印出被调用的参数和名字:
1 | import java.lang.reflect.*; |
通过打印结果可以得知,每次调用代理对象的compareTo方法,都会调用InvocationHandler的invoke方法。这是因为JVM动态生成的代理类生成代理对象时,会传入InvocationHandler实例对象。
然后我们在invoke方法内部通过Method.invoke()方法打印方法名称和参数来进行调用。
特性
代理类只有一个实例域,那就是InvocationHandler。另外,所有的代理类都覆盖了Object类中的方法toString,equals和hashCode。
对于特定的类加载器和预设的一组接口,只能有一个代理类。