• 利用springloaded进行java class动态替换


    我们知道对于一个java文件,如Test.java,首先需要通过javac命令(javac Test.java)进行编译,生成class文件,再将class文件在jvm上进行加载运行,也就是java命令(java Test)。

    但是对于以下应用场景:正在运行的java程序,即class文件已经在jvm中运行加载,如果原来的java程序有所改动,重新生成了class文件,但是又不希望kill掉原先的java程序,该怎么做呢?springloaded提供了一个思路。

    我是在eclipse下实验的,先建立一个SpringloadedTest的工程,在工程下面创建一个Test的java文件,代码如下:

     1 import java.util.concurrent.TimeUnit;
     2 public class Test {
     3 
     4     public static void main(String[] args) throws Exception{
     5         Reload reload = new Reload();
     6         
     7         while (true) {
     8             reload.load();
     9             TimeUnit.SECONDS.sleep(3);
    10         }
    11     }
    12     
    13     public static class Reload {
    14 
    15         public void load() {
    16             System.out.println("load!");
    17         }
    18     }
    19 }

    然后,在项目上右键,Run As->Run Configurations->Arguments->VM arguments,配置如下的参数,也可以在后面加上-Dspringloaded=verbose用来显示详细的重新加载信息(推荐!)

    springloaded-1.2.5.RELEASE.jar可以到官网进行下载:https://github.com/spring-projects/spring-loaded

    为方便起见,我直接把springloaded-1.2.5.RELEASE.jar放在项目src目录下,你也可以放在电脑硬盘的任意位置,配置成相应的路径就行了。

    运行结果如下:

    一开始是load!程序一直在运行当中,在eclipse中更改代码,保存,不用停止程序,运行结果变成reload!

    看起来非常简单!

    但是还是有一些问题:

    1.不利用eclipse,用传统的javac和java命令,行不行?答案是不行,为此我做了一个实验,我先创建了两个文件夹,分别是test和test_replace,test目录下的java文件中是load,test_replace目录下的java文件是reload,然后在test目录下,运行程序java -javaagent:springloaded-1.2.5.RELEASE.jar -noverify Test,输出的是load,再用test_replace目录下的class文件替换test中的class文件,结果还是load,并没有任何改变!

    我怀疑是因为eclipse创建的是一个完整的项目,拥有完整的资源,它的class文件都在bin文件夹下,所以替换之后,项目会自动检测,然后替换jvm中的class。

    2.还要说明的是,class文件时间上也有要求!即替换的class文件要比原先的class文件要晚!如果比原先的class文件早,那么即使替换了,运行结果也不会变化!

    3.注意观察代码,定义了一个静态类Reload,然后main函数中调用,假设如果没有这个类,直接在main函数中进行输出,然后修改输出的内容,行不行?答案是不行,我试过,输出的结果没有变化。为什么?这个问题,我暂时也无法回答,大家有知道的,可以告诉我哈。后来我又试了一下,把输出的内容用一个单独的static函数,这种方式也是可行的。就比如,在main函数中调用这个printHello函数,然后再函数中进行改变,也可以重新加载。

    所以要想动态替换,还需要按照项目的格式要求,在bin目录下进行操作,并且需要注意class的时间问题。

    以上就是关于springloaded的使用介绍,该方法同样适用于jar,但是我还没有试过,后面有机会再试。 

  • 相关阅读:
    为什么不要在Spring的配置里,配置上XSD的版本号
    使用GIT管理UE4代码
    C++ 编程错误记录
    Maven 命令及其他备忘
    Windows API 之 CreateToolhelp32Snapshot
    Windows API 之 ReadProcessMemory
    Windows API 之 OpenProcessToken、GetTokenInformation
    利用未文档化API:RtlAdjustPrivilege 提权实现自动关机
    WindowsAPI 之 CreatePipe、CreateProcess
    错误: error C4996: 'strcpy': This function or variable may be unsafe. Consider using strcpy_s instead. 的处理方法
  • 原文地址:https://www.cnblogs.com/fxl-njfu/p/9283892.html
Copyright © 2020-2023  润新知