使用工具
- 找到
jdk
当中的sa-jdi.jar
的位置,比如在我的电脑上这个jar
包的位置 执行如下所示的命令
D:\>java -classpath "D:\installpackage\programme\java\jdk1.8\lib\sa-jdi.jar" sun.jvm.hotspot.HSDB
执行完成之后会出现一个窗口
运行jsp命令找到进程ID
- 将这里找到的进程ID输入到上面第一步的位置,然后进行如下截图所示操作
如上图所示,因为案例中cglib
代理的是Producer
,所以这里我们搜索Producer
,可以看到下面有一个类就是Producer
,还有一个是cglib
的代理类,我们点击那个cglib
的代理类
点击之后会出现上图所示界面,点击create.class file
即可
有时候代理类的名称不是和我们的类名类似或者有关联的,那么如何根据代理类的名称来查找呢?
如上图所示,我们可以打断点直接看一下代理类的名称,然后拿这个名称去搜索即可。
使用jdk类来生成代理类
还有一种方式可以直接使用jdk
生成类的方式来生成代理类并且使用输出流输出到本地,然后使用反编译工具来查看即可。比如还是上面的那个接口,现在想要生成代理类。
byte[] bytes = ProxyGenerator.generateProxyClass("$Proxy0", new Class[]{NeedProxyInterface.class});
FileOutputStream os = new FileOutputStream("D://$Proxy0.class");
os.write(bytes);
os.close();
这样就可以在D盘看到$Proxy0.class
文件,$Proxy0
这个是我们自己取的代理类的名字。
再使用反编译工具查看发现和我们使用HSDL
查看的工具类时一样的。
如果有多个代理类应该如何找呢?
可以看到当我们点击一个代理类进去后,里面有Interfaces
可以查看这个代理类是实现的哪个接口,我们可以根据这个来找到我们需要的代理类。
直接生成中间代理类
其实还有一种简单的的方式可以直接生成代码在运行过程中产生的代理类。
生成 jdk 代理类
我们可以直接添加jvm运行参数。在idea中如图所示:
-Dsun.misc.ProxyGenerator.saveGeneratedFiles=true
还可以在main方法的第一行直接加上如下所示的代码
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
上面的两种方式是在jdk1.8
中测试是可以的,但是网上看到说新版本(具体哪个就自己测试咯)的jdk
这种方式不行,需要使用下面的代码。
System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles", "true");
同样的,如果在新版本中不想使用代码的方式,也是可以使用jvm
运行参数的形式来设置,那就是在vm options
中设置成如下所示的代码就可以咯。
-Djdk.proxy.ProxyGenerator.saveGeneratedFiles=true
开启之后,就会将中间的代理类生成 class 文件放在 idea 的工程目录中。
使用这种方式可能踩到的坑
生成 cglib 代理类
在 main 方法第一行加上
System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "D:\\temp\\cglib");
然后运行代码就可以在指定的目录中看到在执行过程中生成的 cglib 代理类了。