黑马程序员技术交流社区
标题:
动态代理proxy
[打印本页]
作者:
冯培军
时间:
2012-9-27 17:45
标题:
动态代理proxy
Class clazzProxy1 =
Proxy
.getProxyClass(Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy1.getName());
上面的Proxy是什么意思,它是个类还是一个对象啊,如果是一个类获取字节码class不应该是类名.class么?
张老师在视频中用到proxy是随意找的一个类还是,这个类就是专门用在动态代理上的。如果是用在动态代理上的。它是怎么使用的呢?
作者:
王海宇
时间:
2012-9-27 20:30
是一个专门用于生成动态代理类的字节码的类,这个方法不是返回Proxy类的字节码,而是根据传人参数返回一个动态类的字节码,当然就不能用.class这种形式来获取字节码了
作者:
李健_8
时间:
2012-9-27 22:00
所谓Dynamic Proxy是这样一种class:
它是在运行时生成的class,在生成它时你必须提供一组interface给它,然后该class就宣称它实现了这些interface。你当然可以把该class的实例当作这些interface中的任何一个来用。当然啦,这个Dynamic Proxy其实就是一个Proxy,它不会替你作实质性的工作,在生成它的实例时你必须提供一个handler,由它接管实际的工作。
作者:
李玉生
时间:
2012-9-29 04:54
看了之后,知道了一點
作者:
柳彬
时间:
2012-9-29 09:02
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;
}
}
}
复制代码
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2