java 热编译,热加载

一. 热编译

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;
    }
}

你可能感兴趣的:(java)