保存JDK动态代理字节码的两种方式
如果我们要研究JDK动态生成的代理类,此时则需要将内存中的代理类作为.class文件保存到磁盘,再通过Java反编译工具查看其源码
(方式一)设置系统属性
在调用newProxyInstance之前将sun.misc.ProxyGenerator.saveGeneratedFiles系统属性设置为true,生成的代理类将被自动写入磁盘;class文件在 \Workspaces\项目名称\com\sun\proxy 路径下
public Object getProxy() {
System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true"); //设置系统属性
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
(方式二)保存ProxyGenerator生成的字节流数组
直接通过ProxyGenerator的静态方法generateProxyClass(JDK源码中 P r o x y . n e w P r o x y I n s t a n c e \color{blue}{Proxy.newProxyInstance} Proxy.newProxyInstance实际就是调用 P r o x y G e n e r a t o r . g e n e r a t e P r o x y C l a s s \color{blue}{ProxyGenerator.generateProxyClass} ProxyGenerator.generateProxyClass方法生成的class对应的字节数组)生成代理类的字节数组表示,再通过IO流写到磁盘
代理类的class文件在 \Workspaces\项目名称\bin\目标类所在的包 路径下
public Object getProxy() {
saveClassFile(target.getClass(),"AtmProxy");//调用保存为class字节码文件
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(), this);
}
/**
* 保存class文件
* @param clazz class对象
* @param proxyName 代理类的名字,可随意指定
* @param classBytes
*/
public void saveClassFile(Class clazz,String proxyName) {
//生成class的字节数组,此处生成的class与proxy.newProxyInstance中生成的class除了代理类的名字不同,其它内容完全一致
byte[] classFile = ProxyGenerator.generateProxyClass(proxyName, clazz.getInterfaces());
String path = clazz.getResource(".").getPath();
FileOutputStream fos = null;
try {
fos = new FileOutputStream(path + proxyName + ".class");
fos.write(classFile);//保存到磁盘
fos.flush();
}catch(Exception e) {
e.printStackTrace();
}finally {
try {
fos.close();
}catch(IOException e) {
e.printStackTrace();
}
}
}
类导入问题处理
如果出现Access restriction: The type ‘ProxyGenerator’ is not API (restriction on required library ‘C:\Program Files\Java\jre1.8.0_72\lib\rt.jar’)问题
import sun.misc.ProxyGenerator;
语句无效,会导致 ProxyGenerator cannot be resolved 错误;
原因是 P r o x y G e n e r a t o r \color{blue}{ProxyGenerator} ProxyGenerator 不属于JDK API的内容,默认不给导入
解
决
方
法
\color{blue}解决方法
解决方法:
1.选中工程右键 -> Properties
2.Java build path -> libraries -> JRE System Library
3.点击右侧靠下方Edit
4.选择默认的JRE环境,Workspace default JRE; 或者选择Alternate JRE ->Installed JREs 导入JRE的目录环境
JDK动态代理完整代码
JDK动态代理完整代码请参考专题内容:https://blog.youkuaiyun.com/write6/article/details/89719646#font_size4JDKfont_48