java动态代理类的详细分析_少年小鱼_百度空间
1.java的动态代理可以帮助我们动态的生成字节码文件。
例如:
Class clazz=Proxy.getProxyClass(List.class.getClassLoader(), List.class);
这样我们就建立了一个字节码文件,我们可以通过反射来操作字节码文件做很多事情,例如获取clazz的所有字段、方法、构造方法等。还可以获取器名字(这个名字是$Proxy0,可以通过System.out.println(clazz.getName());获取)

这里我们获取其方法和构造方法。
通过获取,我们可以知道,其只有一个有参数的构造方法,参数类型是java.lang.reflect.InvocationHandler。
于是我们可以获取这个带java.lang.reflect.InvocationHandler参数的构造函数,然后newInstance一个对象。
代码如下:
Constructor constructor = clazz.getConstructor(InvocationHandler.class);
constructor.newInstance(new InvocationHandler(){

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
// TODO Auto-generated method stub
return method.invoke(l, args);
}

});
由于java.lang.reflect.InvocationHandler是一个接口,所以我们这里采用了匿名实现的方式。其实大多数情况下,我们需要的是。一个实现了InvocationHandler接口的类。然后在invoke方法做一些自己的事情就可以了。这里要注意的一点就是invoke方法的method.invoke(l, args);这个参数一定不要使用代理对象的。也就是不要使用proxy,而是使用传进来的源对象。
这是为什么呢?解释一下。我们都知道,代理对象和源对象里的方法是一样的。只是代理对象有一个带java.lang.reflect.InvocationHandler参数的构造函数。我们应该知道,构造函数的作用,就是初始化字段什么的。所以我们可以断定,代理类里面有一个InvocationHandler类型的字段(假设的,其实在clazz中获取的字段中看不出有这个)。
例如,我们执行List的代理类的方法size()的时候。
其实是执行:
public class $Proxy0{
public int size{
return invoke(this, this.getClass().getMethod("size"), new Object[] {});
}
}
如果我们在invoke(this, Method method, Object[] args);{dy}个参数里面写上 代理类的话,将会是死循环。
就是执行代理类的invoke方法,而invoke方法又执行代理类的invoke方法,如此反复。因此这个要用源类。

2.其实以上的过程可以被简化,以上的过程是创建字节码,根据字节码获取构造器、根据构造器new一个代理对象。其实Proxy的Proxy.newProxyInstance(loader, interfaces, h);方法已经帮我们全部搞定了。我们要做的就是创建一个InvocationHandler实现类,然后把自己的源类传递到这个实现类中,就可以得到代理对象了。

http://longdechuanren.javaeye.com/blog/621777


郑重声明:资讯 【java动态代理类的详细分析_少年小鱼_百度空间】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——