(转载https://segmentfault.com/a/1190000011608393)
由于动态代理生成的class是直接以二进制的方式加载进内存中的,并没有对应的.class文件生成,所以如果想通过反编译工具查看动态代理生成的代码需要通过特殊的手段来处理。
方案一
设置运行环境变量,运行后会把class文件生成在classpath目录下
//动态代理时生成class文件
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
缺点是只适用于JDK动态代理
方案二
使用ClassDump,可以dump出JVM中所有已加载的class。ClassDump位于$JAVA_HOME/lib/sa-jdi.jar中(注:windows版本JDK从1.7开始才有此工具),直接以命令行执行。
查看PID
E:\work\Test\bin>jps
缺省输出该PID下所有已加载的class文件至./目录
E:\work\Test\bin>java -classpath ".;./bin;%JAVA_HOME%/lib/sa-jdi.jar" sun.jvm.hotspot.tools.jcore.ClassDump <PID>
//导入sa-jdi.jar包,实现ClassFilter接口,只输出匹配的class文件
public class MyFilter implements ClassFilter{
@Override
public boolean canInclude(InstanceKlass arg0) {
return arg0.getName().asString().startsWith("com/sun/proxy/$Proxy0");
}
}
查看PID
E:\work\Test\bin>jps
使用ClassFilter输出匹配的class文件,并指定输出目录
E:\work\Test\bin>java -classpath ".;./bin;%JAVA_HOME%/lib/sa-jdi.jar" -Dsun.jvm.hotspot.tools.jcore.filter=proxy.MyFilter -Dsun.jvm.hotspot.tools.jcore.outputDir=e:/dump sun.jvm.hotspot.tools.jcore.ClassDump <PID>
此方案基于JVM层的ClassDump所以可以支持javassist、cglib、asm动态生成的class。
网友评论