Proxy
Proxy 代理,提供1种代理的方式去访问对象,
相关类
java.lang.reflect.Proxy;
java.lang.reflect.InvocationHandler;
原理
Proxy 调用 vm,根据给定的接口,创建 1个 Class 对象(给 Class 类型 实现给定的接口)
创建 InvocationHandler 的实现类,添加 1个属性 符合上面 指定的接口类型,该属性是真正的想操作的对象,
在 invoke() 方法用,使用该对象来调用方法,而不是传入的对象,
然后创建 1个 InvocationHandler 实现类 的对象,
调用 Proxy 创建的 Class 对象,用代理构造函数,借助 上面 InvocationHandler 实现类 的 1个对象,创建 1个 接口类型的 代理对象,
该 代理对象 将代理了上面 InvocationHandler 实现类中用做数据的对象,
当调用这个 对象时,实际上是调用了 InvocationHandler 中的数据对象,
从而实现了代理----
代理实现
2种格式实现代理,分别使用了 Proxy 的2个不同方法,配合 InvocationHandler 实现,
* 前提:
实现 InvocateHandler 类:
创建1个 InvocationHandler 实现类,其中包含1个属性是真正要操作的对象,提供1个构造函数,用于从外部传入该属性,
* Proxy.getProxyClass() 方式
步骤:
用 Proxy.getProxyClass() 创建 代理 Class 对象,
然后创建 代理 Constructor,
然后创建 代理 对象,
这样 操作 代理对象时,实际是 InvocationHandler 对象 从操作其中的 属性 完成方法调用,
* Proxy.newProxyInstance() 方式
步骤:
用 Proxy.newProxyInstance 直接创建 代理对象,
创建过程中,同样 需要 1个 InvocationHandler 类型的 对象,
*例子- package eric.j2se.reflect.proxy;
- import java.lang.reflect.Constructor;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- /**
- * Proxy test
- *
- * @author eric
- * @date 2011-2-24 下午06:05:09
- */
- public class ProxyTest {
- public static void main(String[] args) {
- testProxyOne();
- testProxyTwo();
- }
- /**
- * Proxy.getProxyClass() 方式,步骤: 1 创建 代理 Class 对象,2 然后创建 代理 Constructor,3 然后创建 代理对象,
- */
- @SuppressWarnings("unchecked")
- public static void testProxyOne() {
- try {
- // create a Class object,with Proxy.getProxyClass()
- Class proxyClazz = Proxy.getProxyClass(List.class.getClassLoader(), List.class);
- System.out.println(Proxy.isProxyClass(proxyClazz));
- // 真正 要操作的 对象
- List data = new ArrayList();
- // create InvocationHandler instance
- InvocationHandler ih = new MyInvocateHandler(data);
- // 创建 构造函数,用 InvocationHandler 作为参数,可以用于创建 代理对象
- Constructor cst = proxyClazz.getConstructor(InvocationHandler.class);
- // 创建 代理对象
- List<Integer> list = (List<Integer>) cst.newInstance(ih);
- // 调用方法
- list.add(1);
- list.add(2);
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- }
- /**
- * Proxy.newProxyInstance 方式,直接创建 代理对象,
- */
- @SuppressWarnings("unchecked")
- public static void testProxyTwo() {
- // 真正 要操作的 对象
- List data = new ArrayList();
- // 用 Proxy.newProxyInstance 直接创建 代理对象,
- List<Integer> list = (List<Integer>) Proxy.newProxyInstance(List.class.getClassLoader(),
- new Class[] { List.class }, new MyInvocateHandler(data));
- // 调用 代理对象
- list.add(100);
- list.add(200);
- }
- /**
- * 自定义 InvocationHandler 实现类,提供了传入 真正对象的 构造函数,
- *
- * @author eric
- * @date 2011-2-28 下午07:10:11
- */
- static class MyInvocateHandler implements InvocationHandler {
- /**
- * 该构造函数 可以设置 真正的 对象
- *
- * @param data 真正要操作的对象
- */
- public MyInvocateHandler(List<?> data) {
- this.data = data;
- }
- // use this object to invoke method,not the one in arg list of invoke()
- private List<?> data;
- @Override
- public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
- // before method invode
- // 这里使用 自己创建的对象调用方法,而不是 参数中的,参数中的对象只相当于1个代理,
- Object o = method.invoke(this.data, args);
- System.out.println(method.getName() + "(),params:" + Arrays.asList(args));
- // after method invode
- return o;
- }
- }
- }
复制代码 |