场景:例如在运行时想要查看动态代理创建的代理类。
-
启动项目
-
打开HSDB ( 在你的JAVA_HOME/lib目录下,找到sa-jdi.jar )
- 在此目录下打开cmd界面
- 通过命令启动HSDB工具
java -classpath sa-jdi.jar "sun.jvm.hotspot.HSDB"
- 点击file -> 选择Attach to HotSpot process
出现了这个界面,要求输入Java进程的Pid (进程ID)
- 获取进程ID
- 通过指令
netstat -aon | findstr "端口号"
2. 通过Java工具 (项目启动时显示在日志)
public static int getPid() {
final String processName = ManagementFactory.getRuntimeMXBean().getName();
if (StringUtils.isBlank(processName)) {
throw new RuntimeException("Process name is blank!");
}
final int atIndex = processName.indexOf('@');
if (atIndex > 0) {
return Integer.parseInt(processName.substring(0, atIndex));
} else {
return processName.hashCode();
}
}
-
输入进程ID
出现了这样的界面,显示所有的线程
- 点击Tools,选择 Class Browser (Class文件浏览)
- 出现一个窗口,首先通过关键字查找,找到JDK实现的代理类
- 当然,在上面看的不够直观,可以将Class文件存起来,转移到IDEA反编译查看
- 点击Create .class File,将Class文件转储
- 地址为你打开HSDB工具的目录,在这里找到Class文件
- 转移到Idea反编译查看
-
可以看到,代理类继承了Proxy,实现了我们自己的接口,所以这就是为什么JDK动态代理只能实现接口。
-
因为Java是单继承,已经继承了Proxy类,无法再继承其他的类,但是代理类又需要原始接口的方法,所以只能实现接口,获取方法。
问题:
- 在命令行启动HSDB工具时,可能会出现找不到 sawingbg.dll 的情况,它有可能被安装到了JDK目录下的jre/bin目录下,请将它复制到jre/bin目录下即可。
E:\CodeSoftware\jdk1.8.0_181\jre\bin\sawingbg.dll --> E:\CodeSoftware\jre1.8.0_181\bin\sawingbg.dll