自定义类加载器实现热部署

使用该加载器 利用反射获取特定类 当类被重新编译时 代码自动更新了

@AllArgsConstructor
public class MyClassLoader extends ClassLoader {
    private String rootDir;

    @SneakyThrows
    @Override
    public Class<?> findClass(String name) throws ClassNotFoundException {
        Class<?> clazz = this.findLoadedClass(name);
        FileChannel fileChannel = null;
        WritableByteChannel outChannel = null;
        if (clazz == null) {
            try {
                String classFile = getClassFile(name);
                FileInputStream fis = new FileInputStream(classFile);
                fileChannel = fis.getChannel();
                ByteArrayOutputStream baos = new ByteArrayOutputStream();
                outChannel = Channels.newChannel(baos);
                ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
                while (true) {
                    int i = fileChannel.read(buffer);
                    if (i == 0 || i == -1) {
                        break;
                    }
                    buffer.flip();
                    outChannel.write(buffer);
                    buffer.clear();
                }
                byte[] bytes = baos.toByteArray();
                clazz = defineClass(name, bytes, 0, bytes.length);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fileChannel != null) {
                    fileChannel.close();
                }
                if (outChannel != null) {
                    outChannel.close();
                }
            }
        }
        return clazz;
    }

    private String getClassFile(String name) {
        return rootDir + "/" + name.replace(".", "/") + ".class";
    }

}

测试

public class LoadDemo {
    public static void main(String[] args) throws Exception {
        while (true) {
            MyClassLoader loader = new MyClassLoader("/Users/develop/study/webdemo/src/main/java");
            Class<?> clazz = loader.findClass("cn.bb.webdemo.jvm.Hello");
            Object obj = clazz.newInstance();
            Method method = clazz.getMethod("run");
            System.out.println(method.invoke(obj));
            Thread.sleep(3000);
        }
    }
}

Hello 类

public class Hello {
    public static String run() {
        return "hello" ;
    }
}

注意 因为路径是在Hello下 需要使用 修改Hello类重新用 javac命令编译

测试截图

自定义类加载器实现热部署_第1张图片

你可能感兴趣的:(jvm,java,jvm,开发语言)