最近在学习反射,其中涉及到Proxy,InvocationHandler类。我有一个不明白的地方,希望高手赐教,问题如下: interface Foo { void foo(); }
InvocationHandler handler = new MyInvocationHandler(...);
Class proxyClass = Proxy.getProxyClass( Foo.class.getClassLoader(), new Class[] { Foo.class } );因为是动态代理,所以被代理类可以在运行时给定,现在问题是已经知道proxyClass对象,如何才能获取proxyClass的字节码。
InvocationHandler handler = new MyInvocationHandler(...);
Class proxyClass = Proxy.getProxyClass( Foo.class.getClassLoader(), new Class[] { Foo.class } );因为是动态代理,所以被代理类可以在运行时给定,现在问题是已经知道proxyClass对象,如何才能获取proxyClass的字节码。
代码如下:import java.io.File;
import java.io.FileOutputStream;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;import sun.misc.ProxyGenerator;interface Foo {
void foo();
}class MyInvocationHandler implements InvocationHandler { // 被代理对象
private Object real; //可以在运行时刻动态改变被代理类的实例,所以才叫 动态 代理
public void setReal(Object real) {
this.real = real;
} @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if (real == null) {
System.out.println("未设置代理对象");
return null;
}
System.out.println("before " + method.getName());
Object result = method.invoke(real, args);
System.out.println("after " + method.getName());
return result;
}}public class ByteCode { public static void main(String[] args) throws Exception {
Class<?> proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader (), new Class[] { Foo.class });
// 现在要得知proxyClass的字节码,如下,ProxyGenerator类是生产代理类的字节码
byte[] byteCode = ProxyGenerator.generateProxyClass(proxyClass
.getName(), new Class[] { Foo.class });
FileOutputStream fos = new FileOutputStream(new File(
"ProxyClassByteCode.class"));
fos.write(byteCode);
fos.flush();
fos.close();
}
}
程序运行结束后,生成ProxyClassByteCode.class文件,此文件就是类的字节码文件,用jd-gui.exe打开,就可以得到代理类的源码了。
jd-gui是用C++写的java反编译器,速度很快,附下载链接:http://java.decompiler.free.fr/jd-gui/downloads/jd-gui-0.3.2.windows.zip