Java基于自定义类加载器如何实现热部署

  介绍

这篇文章主要介绍Java基于自定义类加载器如何实现热部署,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

热部署:

热部署就是在不重启应用的情况下,当类的定义即字节码文件修改后,能够替换该班级创建的对象。一般情况下,类的加载都是由系统自带的类加载器完成,且对于同一个全限定名的Java类,只能被加载一次,而且无法被卸载。可以使用自定义的类加载器替换系统的加载器,创建一个新的类加载器,再用它加载类,得到的类对象就是新的(因为不是同一个类加载器),再用该课程对象创建一个实例,从而实现动态更新。如:修改JSP文件即生效,就是利用自定义的类加载器实现的。

还需要创建一个守护线程,不断地检查类文件是否被修改过,通过判断文件的上次修改时间实现。

演示:

原来的程序:

癑ava基于自定义类加载器如何实现热部署"

修改后重新编译:

癑ava基于自定义类加载器如何实现热部署"

代码:

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   null

Java基于自定义类加载器如何实现热部署