Java 动态代理机制分析及扩展,第 2 部分
2010-02-24 00:00:00 来源:WEB开发网动态编译及装载
代码生成以后,需要经过编译生成 JVM 所能识别的字节码,而字节码还需要通过类装载器载入 JVM 才能最终被真正使用,接下来我们将阐述如何动态编译及装载。
首先是动态编译。这部分由 ProxyEx 类的 getProxyClassCodeSource 函数完成。该函数分三步进行:第一步保存源代码到 .java 文件;第二步编译该 .java 文件;第三步从输出的 .class 文件读取字节码。
清单 13. ProxyEx 的静态方法 getProxyClassCodeSource
private static byte[] getProxyClassCodeSource( String pkg, String className,
String declare ) throws Exception
{
// 将类的源代码保存进一个名为类名加“.java”的本地文件
File source = new File(className + ".java");
FileOutputStream fos = new FileOutputStream( source );
fos.write( declare.getBytes() );
fos.close();
// 调用com.sun.tools.javac.Main类的静态方法compile进行动态编译
int status = com.sun.tools.javac.Main.compile( new String[] {
"-d",
".",
source.getName() } );
if( status != 0 )
{
source.delete();
throw new Exception("Compiler exit on " + status);
}
// 编译得到的字节码将被输出到与包结构相同的一个本地目录,文件名为类名加”.class”
String output = ".";
int curIndex = -1;
int lastIndex = 0;
while( (curIndex=pkg.indexOf('.', lastIndex)) != -1 )
{
output = output + File.separator + pkg.substring( lastIndex, curIndex );
lastIndex = curIndex + 1;
}
output = output + File.separator + pkg.substring( lastIndex );
output = output + File.separator + className + ".class";
// 从输出文件中读取字节码,并存入字节数组
File target = new File(output);
FileInputStream f = new FileInputStream( target );
byte[] codeSource = new byte[(int)target.length()];
f.read( codeSource );
f.close();
// 删除临时文件
source.delete();
target.delete();
return codeSource;
}
更多精彩
赞助商链接