有时,必须像脚本一样运行java。 此外,如果代码是热部署,并且代码文件发生更改,我希望您重新加载该代码,可以实现吗? 今天试着解决吧。
自定义类加载器
我们需要自定义的类加载器,完成任何路径(包括网络)的文件加载。 这将获取java字节码文件,也就是编译的class文件。 他可能在世界的某个地方。
实现自定义的类加载器首先继承名为ClassLoader的类来构建方法代码
publicclassmyclassloadextendsclassloader {
私有字符串根路径;
publicmyclassload (字符串根路径)。
this.rootPath=rootPath;
}
}
生成方法只有路径导入,即class文件中的文件夹,不包含软件包名称的路径
接着重写findClass方法;
//*
根据name查找类
*
*/
@Override
protectedclassfindclass (字符串名称) throws ClassNotFoundException {
classc=findloadedclass(name;
if(c==null )//内存堆中未加载类
c=findmyclass(name; //自行安装加载类
}
返回c;
}
首先在内存堆栈中查找,如果没有加载,自己实现,看看如何查找我的类
//*
*加载此类
*
* @param name
* @return
*/
privateclassfindmyclass{
try {
byte[]bytes=getdata(name;
returnthis.defineclass(null,bytes,0,bytes.length ); //调用父类方法并生成具体类
}catch(exceptione ) {
e .打印堆栈跟踪(;
}
返回空值;
}
此方法根据字节数组返回Class类。 要从Class文件中检索字节数组,请使用Apache文件处理相关的辅助类。 在此使用本机jdk实现。
private byte [ ] get data (字符串类名称)。
string path=root pathfile.separatorcharclassname.replace '.',file.separatorchar'.class ';
InputStream is=null;
try {
is=new file inputstream (路径;
bytearrayoutputstreamstream=newbytearrayoutputstream (;
byte[] buffer=new byte[2048];
int num=0;
wile((num=is.read ) ) Buffer )!=-1 ()
stream.write(buffer,0,num );
}
return stream.toByteArray (;
}catch(ioexceptione ) {
e .打印堆栈跟踪(;
} finally {
if(is!=空) {
try {
is.close (;
}catch(ioexceptione ) {
e .打印堆栈跟踪(;
}
}
}
返回空值;
}
这个简单的自定义类加载器差不多。 如果需要实现自己的加密解密,可以在字节数组中费力。 我不会在这里再深挖下去了。 我们的目标是热加载java代码。 可能的解决方案是构建一个包含几个方法的java模板。 可以从外部添加新方法,也可以调用内置方法。
好的! 把简单的代码加载到内存中执行吧。
import java.io.File;
import java.io.FileWriter;
import javax.tools.JavaCompiler;
import javax.tools.Java compiler.compilation task;
导入类load.my类load;
import javax.tools.Java文件对象;
import javax.tools.standardjavafilemanager;
导入javax.tools.tool provider;
公共类加载Java {
publicstaticfinalstringjavacode='包类加载; 公共类hello world2{公共hello world2(} (system.out.println (hello world () ); } ();
publicstaticvoidrunjavacode throws exception { }
将Java字符串保存到文件
string filename='/users/XXXXXX/documents/demo/Java/class load/hello world2. Java ';
文件文件=new file (filename;
filewriter fw=new filewriter (文件;
Fw.write (Java代码;
fw.flush (;
fw.close (;
//
javacompilerjavacompiler=tool provider.getsystemjavacompiler (;
sandardjavafilemanagerstandardfilemanager=Java compiler.getstandardfilemanager (null、null、null );
iterableextendsjavafileobjectiterable=标准文件管理器. getjavafileobjects (filename );
//执行编译任务
compilation tasktask=Java compiler.get task (null,standardFileManager,null,null,iterable );
task.call (;
标准文件管理器. close (;
//将编译的class文件加载到内存中
class loader PCL=newmyclassload (/users/XXXXXX/documents/demo/Java/' );
class c=PCL.load class (class load.hello world2);
system.out.println (c.new instance );
}
publicstaticvoidmain (字符串[ ] args ) {
try {
load Java.run Java代码(;
}catch(exceptione ) {
e .打印堆栈跟踪(;
}
}
}
代码注释很清楚,请不要再说了。
版权将在你的作品上打印版权32805660