一. 热编译
package com.lucain.dynamic;
import sun.applet.AppletClassLoader;
import sun.misc.Launcher;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* Created by luxian.zhang on 2017/7/27.
*/
public class Test {
/**
* 创建java文件
* @author Lucian
*/
public static File generateJava() throws Exception{
// 1.创建需要动态编译的代码字符串
String nr = "\r\n"; //回车
String source = "package com.lucian; " + nr +
" public class Hello{" + nr +
" public void hello(){" + nr +
" System.out.println(\"HelloWorld! 1\");" + nr +
" }" + nr +
" }";
File dir = new File(CustomizationClassLoader.sourcePath);
if(!dir.exists()){
dir.mkdirs();
}
File file = new File(dir,"Hello.java");
Writer writer = new FileWriter(file);
try {
writer.write(source);
} catch (IOException e) {
e.printStackTrace();
} finally {
writer.flush();
writer.close();
}
return file;
}
/**
* 编译java文件
*/
public static void compilerJava(File file) throws Exception{
// 取得当前系统的编译器
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
//获取一个文件管理器
StandardJavaFileManager javaFileManager = javaCompiler.getStandardFileManager(null, null, null);
try {
//文件管理器与文件连接起来
Iterable it = javaFileManager.getJavaFileObjects(file);
File dir = new File(CustomizationClassLoader.classPath);
if(!dir.exists()){
dir.mkdirs();
}
//创建编译任务
JavaCompiler.CompilationTask task = javaCompiler.getTask(null, javaFileManager, null, Arrays.asList("-d", CustomizationClassLoader.classPath), null, it);
//执行编译
task.call();
} catch (Exception e) {
e.printStackTrace();
} finally {
javaFileManager.close();
}
}
public static void main(String[] args) throws Exception{
compilerJava(generateJava());
CustomizationClassLoader classLoader = new CustomizationClassLoader();
Class cl = classLoader.loadClass("com.lucian.Hello");
Object obj = cl.newInstance();
Method helloMethod = cl.getMethod("hello", null);
helloMethod.invoke(obj, null);
}
}
二. 热加载
自定义类加载器,实现热加载
package com.lucain.dynamic;
import java.io.FileInputStream;
/**
* Created by luxian.zhang on 2017/7/27.
*/
public class CustomizationClassLoader extends ClassLoader{
public static String classPath;
public static String sourcePath;
static {
classPath = System.getProperty("user.dir") + "/temp/class";
sourcePath = System.getProperty("user.dir")+"/temp/source";
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] data = loadByte(name);
return defineClass(name, data, 0, data.length);
} catch (Exception e) {
e.printStackTrace();
throw new ClassNotFoundException();
}
}
/**
* 加载class文件,转换为字节数组
*/
private byte[] loadByte(String name) throws Exception {
name = name.replaceAll("\\.", "/");
FileInputStream fis = new FileInputStream(classPath + "/" + name
+ ".class");
int len = fis.available();
byte[] data = new byte[len];
fis.read(data);
fis.close();
return data;
}
}