java热部署的简单介绍

简单介绍

在类加载器中,类只可以加载一次并且不可卸载。java类只能被加载一次,并且无法卸载。想要实现热部署可以分以下三个步骤:
1、销毁该自定义ClassLoader
2、更新class类文件
3、创建新的ClassLoader去加载更新后的class类文件。

源码部分

  1. 自定义类加载器

    import java.io.InputStream;
    public class MyClassLoader extends ClassLoader {
        @Override
        public Class<?> findClass(String name) throws ClassNotFoundException {
            try {
                String fileName = name.substring(name.lastIndexOf("." )+1) + ".class" ;
                InputStream inputStream = this.getClass().getResourceAsStream(fileName);
                byte[] b = new byte[inputStream.available()];
                inputStream.read(b);
                return defineClass(name, b, 0, b.length);
            } catch (Exception e) {
                throw new ClassNotFoundException(name);
            }
        }  
    }
  2. 替换的类

//class 1
public class Helloword {
    public void say() {
        System.out.println("Hello world! V1");
    }
}

//class2
public class Helloword {
    public void say() {
        System.out.println("Hello world! V2");
    }
}
  1. 测试类
public class App 
{
    public static void main( String[] args ) throws Exception
    {
        loadHelloWorld();
        System.gc();//等待gc回收
        Thread.sleep(3* 1000);
        File fileV2 = new File("Helloword2.class");
        File fileV1 = new File("target/classes/com/mirsery/test/Helloword.class");
        fileV1.delete();
        fileV2.renameTo(fileV1);
        System.out.println("Update Success!");
        loadHelloWorld();
    }

    public static void loadHelloWorld() throws Exception {
        MyClassLoader myClassLoader = new MyClassLoader();
        Class<?> class1 = myClassLoader.findClass("com.test.Helloword");
        Object obj = class1.newInstance();
        Method method = class1.getMethod( "say");
        method.invoke(obj);
        System.out.println(obj);
        System.out.println(obj.getClass());
        System.out.println(obj.getClass().getClassLoader());
    }

}