---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------详细请查看:http://edu.csdn.net
代理模式:
JAVA动态代理类位于java.lang.reflect包下,一般主要涉及到以下两个类:
1.Interface InvocationHandle该接口中仅定义了一个方法:public object invoke(Object obj,Method method,Object[] args)
在实际使用时,第一个参数obj一般是指代理类,method是被代理的方法,如上例中的request(),args为该方法的参数数组。这个抽象方法在代理类中动态实现。
2.Proxy:该类即为动态代理类,作用类似于上例中的proxySubject
下面是利用代理动态生成类对象。上面构造方法中要接收一个带invocationHander的参数,所以紧跟着要实现这个接口。然后才可newInstance。上面调用 size方法时会发生错误, 原因可以在下面一段代码中找, 因为 我调用 size方法,但size方法的返回值为int ,但Invoke返回的确是 Null所以就会发生错误。
Class clazzprox = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
Constructor[] constructors = clazzprox.getConstructors();
for(Constructor c : constructors)
{
String name = c.getName();
StringBuilder s = new StringBuilder(name);
s.append("(");
Class[] p = c.getParameterTypes();
for(Class cla : p)
{
s.append(cla.getName()).append(",");
}
s.append(")");
System.out.println(s);
}
}
Constructor constructor = clazzProxy1.getConstructor
class MyInvocationHander1 implements InvocationHandle{
public Object invoke(Object proxy, Method method) throws Throwable{
return null;
}
}
collection proxy1 = (Collection)constructor.newInstance();
System.out.println(proxy1);
proxy1.clear();
让JVM创建动态类及其实例对象,需要给它提供的信息如下:
1.生成的类中有哪些方法,通过让其实现哪些接口的方式进行告知;
2.产生的类字节码必须有个一个关联的类加载器对象;
3.生成的类中的方法的代码是怎样的,也得由我们提供。把我们的代码写在一个约定好了接口对象的方法中,把对象传给它,它调用我的方法,即相当于插入我的代码。提供执行代码的对象就是那个InvocationHandler对象,它是在创建动态类的实例对象的构造方法时传递进去的。在上面的InvocationHandler对象的invoke方法中加一点代码,就可以看到这些代码被调用运行了。
用Proxy.newInstance方法直接一步就创建出代理对象。
最后 可以 用Proxy.newInstance 方法直接创建对象,不用向上面那样麻烦了。
//用Proxy.newProxyInstance()方法,直接动态创建类
Collection c3 = (Collection)Proxy.newProxyInstance(
Collection.class.getClassLoader(),
new Class[]{Collection.class},
new InvocationHandler(){
//放在这里面 就不是 每次创建 一个arrayList对象了。
//ArrayList al = new ArrayList();
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
ArrayList al = new ArrayList();
long beginTime = System.currentTimeMillis();
Object o = method.invoke(al, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + " time: "+
(endTime - beginTime));
return o;
}
});
c3.add("aaa");
c3.add("bbb");
c3.add("ccc");
System.out.println(c3.size());
输出结果:
add time: 0
add time: 0
add time: 0
size time: 0
0
这是上面代码的输出结果,为什么会输出 0 ? 因为每add 或 调用size 方法时,就会去调用invoke方法,而arrayList是在invoke方法里面new 出来的,所以每次都是不同的对象,所以 size为0, 如果把new arrayList 方法类里面结果就会输出 3 。
Proxy 从objectg 身上继承的方法 , 只有 hashCode,equals,toString 会给InvocationHanderl 自己,所以上面打印对象时,由于返回值是null 所以才会打印null。其他的方法 都有实现 。
总结动态代理的步骤:
1.创建一个实现接口InvocationHandler的类,它必须实现invoke方法。
2.创建被代理的类以及接口。
3.通过Proxy的静态方法newProxyInstance(ClassLoader loader,Class[] interfaces,InvocationHandler);创建一个代理。
4.通过代理调用方法。
本文深入探讨了Java动态代理的核心概念,包括InterfaceInvocationHandler接口和Proxy类的使用方式,并通过示例代码展示了如何创建动态代理对象及其工作原理。

243

被折叠的 条评论
为什么被折叠?



