介绍
这篇文章主要介绍Java基于自定义类加载器如何实现热部署,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
热部署:
热部署就是在不重启应用的情况下,当类的定义即字节码文件修改后,能够替换该班级创建的对象。一般情况下,类的加载都是由系统自带的类加载器完成,且对于同一个全限定名的Java类,只能被加载一次,而且无法被卸载。可以使用自定义的类加载器替换系统的加载器,创建一个新的类加载器,再用它加载类,得到的类对象就是新的(因为不是同一个类加载器),再用该课程对象创建一个实例,从而实现动态更新。如:修改JSP文件即生效,就是利用自定义的类加载器实现的。
还需要创建一个守护线程,不断地检查类文件是否被修改过,通过判断文件的上次修改时间实现。
演示:
原来的程序:
修改后重新编译:
代码:
package 动态; , import . io . *; import java.nio.file.Files; import java.nio.file.Path; import java.util.concurrent.TimeUnit; , public class  ClassLoadStudy { public 才能;static  void main (String [], args), throws Exception { ,,,HotDeploy 热;=,new 热部署(“Dynamic.Task"); ,,,hot.monitor (); ,,,while (真实),{ ,,,,,TimeUnit.SECONDS.sleep (2); ,,,,,hot.getTask () .run (); ,,,} ,,} } ,//,热部署 , class HotDeploy  { private 才能static volatile  Runnable 实例; private 才能final String  FILE_NAME; private 才能final String  CLASS_NAME; , public 才能;热部署(String 名称),{ ,,,CLASS_NAME =,名字,,//,类的完全限定名 ,,,name =, name.replaceAll (“\ \ !”,,“/?, +,“.class"; ,,,FILE_NAME =, (getClass () .getResource(“/?, +,名字).substring(6),,//,判断类文件修改时间使用,子串(6)去掉开头的文件:/,,} ,//,才能获取一个任务 public 才能;Runnable  getTask (), { ,,,if (instance ==, null),{,//双重检查锁,单例,线程安全 ,,,,,synchronized (HotDeploy.class), { ,,,,,,,if (instance ==, null), { ,,,,,,,,,try { ,,,,,,,,,,,instance =, createTask (); ,,,,,,,,,},catch (Exception e), { ,,,,,,,,,,,e.printStackTrace (); ,,,,,,,,,} ,,,,,,,} ,,,,,} ,,,} ,,,return 实例; ,,} ,//,才能创建一个任务,重新加载,class 文件 private 才能;Runnable  createTask (), { ,,,try { ,,,,,Class clazz =, MyClassLoader.getLoader () .loadClass (CLASS_NAME); ,,,,,if (clazz !=, null) ,,,,,,,return (Runnable) clazz.newInstance (); ,,,},catch (Exception e), { ,,,,,e.printStackTrace (); ,,,} ,,,return 零; ,,} , ,//才能,监视器,监视类文件是否被修改过,如果是的话,则重新加载 public 才能;void 显示器(),throws IOException { ,,,Thread t =, new 线程(()→{ ,,,,,try { ,,,,,,,long lastModified =, Files.getLastModifiedTime (Path.of (FILE_NAME)) .toMillis (); ,,,,,,,,(真正的),{ ,,,,,,,,,thread . sleep (500); ,,,,,,,,,long 你=,Files.getLastModifiedTime (Path.of (FILE_NAME)) .toMillis (); ,,,,,,,,,如果(你!=,lastModified),{,//如果类文件被修改过了 ,,,,,,,,,,,lastModified =,现在; ,,,,,,,,,,,instance =, createTask();,//,重新加载 ,,,,,,,,,} ,,,,,,,} ,,,,,},catch (InterruptedException |, IOException e), { ,,,,,,,e.printStackTrace (); ,,,,,} null null null null null null null null null null null null null null null null null null null null null null nullJava基于自定义类加载器如何实现热部署