A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 冯培军 中级黑马   /  2012-9-27 17:45  /  1770 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
                System.out.println(clazzProxy1.getName());
上面的Proxy是什么意思,它是个类还是一个对象啊,如果是一个类获取字节码class不应该是类名.class么?
张老师在视频中用到proxy是随意找的一个类还是,这个类就是专门用在动态代理上的。如果是用在动态代理上的。它是怎么使用的呢?

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

4 个回复

倒序浏览
是一个专门用于生成动态代理类的字节码的类,这个方法不是返回Proxy类的字节码,而是根据传人参数返回一个动态类的字节码,当然就不能用.class这种形式来获取字节码了

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
所谓Dynamic Proxy是这样一种class:
它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 很给力!

查看全部评分

回复 使用道具 举报
看了之后,知道了一點
回复 使用道具 举报
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 类型的 对象,

*例子
  1. package eric.j2se.reflect.proxy;

  2. import java.lang.reflect.Constructor;
  3. import java.lang.reflect.InvocationHandler;
  4. import java.lang.reflect.InvocationTargetException;
  5. import java.lang.reflect.Method;
  6. import java.lang.reflect.Proxy;
  7. import java.util.ArrayList;
  8. import java.util.Arrays;
  9. import java.util.List;

  10. /**
  11. * Proxy test
  12. *
  13. * @author eric
  14. * @date 2011-2-24 下午06:05:09
  15. */
  16. public class ProxyTest {
  17.         public static void main(String[] args) {
  18.                 testProxyOne();
  19.                 testProxyTwo();
  20.         }

  21.         /**
  22.          * Proxy.getProxyClass() 方式,步骤: 1 创建 代理 Class 对象,2 然后创建 代理 Constructor,3 然后创建 代理对象,
  23.          */
  24.         @SuppressWarnings("unchecked")
  25.         public static void testProxyOne() {
  26.                 try {
  27.                         // create a Class object,with Proxy.getProxyClass()
  28.                         Class proxyClazz = Proxy.getProxyClass(List.class.getClassLoader(), List.class);
  29.                         System.out.println(Proxy.isProxyClass(proxyClazz));

  30.                         // 真正 要操作的 对象
  31.                         List data = new ArrayList();
  32.                         // create InvocationHandler instance
  33.                         InvocationHandler ih = new MyInvocateHandler(data);

  34.                         // 创建 构造函数,用 InvocationHandler 作为参数,可以用于创建 代理对象
  35.                         Constructor cst = proxyClazz.getConstructor(InvocationHandler.class);
  36.                         // 创建 代理对象
  37.                         List<Integer> list = (List<Integer>) cst.newInstance(ih);
  38.                         // 调用方法
  39.                         list.add(1);
  40.                         list.add(2);
  41.                 } catch (SecurityException e) {
  42.                         e.printStackTrace();
  43.                 } catch (NoSuchMethodException e) {
  44.                         e.printStackTrace();
  45.                 } catch (IllegalArgumentException e) {
  46.                         e.printStackTrace();
  47.                 } catch (InstantiationException e) {
  48.                         e.printStackTrace();
  49.                 } catch (IllegalAccessException e) {
  50.                         e.printStackTrace();
  51.                 } catch (InvocationTargetException e) {
  52.                         e.printStackTrace();
  53.                 }
  54.         }

  55.         /**
  56.          * Proxy.newProxyInstance 方式,直接创建 代理对象,
  57.          */
  58.         @SuppressWarnings("unchecked")
  59.         public static void testProxyTwo() {
  60.                 // 真正 要操作的 对象
  61.                 List data = new ArrayList();
  62.                 // 用 Proxy.newProxyInstance 直接创建 代理对象,
  63.                 List<Integer> list = (List<Integer>) Proxy.newProxyInstance(List.class.getClassLoader(),
  64.                                 new Class[] { List.class }, new MyInvocateHandler(data));
  65.                 // 调用 代理对象
  66.                 list.add(100);
  67.                 list.add(200);
  68.         }

  69.         /**
  70.          * 自定义 InvocationHandler 实现类,提供了传入 真正对象的 构造函数,
  71.          *
  72.          * @author eric
  73.          * @date 2011-2-28 下午07:10:11
  74.          */
  75.         static class MyInvocateHandler implements InvocationHandler {
  76.                 /**
  77.                  * 该构造函数 可以设置 真正的 对象
  78.                  *
  79.                  * @param data 真正要操作的对象
  80.                  */
  81.                 public MyInvocateHandler(List<?> data) {
  82.                         this.data = data;
  83.                 }

  84.                 // use this object to invoke method,not the one in arg list of invoke()
  85.                 private List<?> data;

  86.                 @Override
  87.                 public Object invoke(Object obj, Method method, Object[] args) throws Throwable {
  88.                         // before method invode
  89.                         // 这里使用 自己创建的对象调用方法,而不是 参数中的,参数中的对象只相当于1个代理,
  90.                         Object o = method.invoke(this.data, args);
  91.                         System.out.println(method.getName() + "(),params:" + Arrays.asList(args));
  92.                         // after method invode
  93.                         return o;
  94.                 }
  95.         }
  96. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
刘芮铭 + 1 赞一个!

查看全部评分

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马