利用springloaded进行java class动态替换

摘要:
我们知道对于java文件,例如Test。java,您需要首先通过javac命令(javacTest.java)编译它以生成类文件,然后在jvm上加载并运行类文件,即java命令(javaTest)。但对于以下应用程序场景:正在运行的java程序,即类文件已加载到jvm中。如果原始java程序发生了更改,则会重新生成类文件,但您不希望终止原始jav

我们知道对于一个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进行java class动态替换第1张

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

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

运行结果如下:

利用springloaded进行java class动态替换第2张

一开始是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函数,然后再函数中进行改变,也可以重新加载。

利用springloaded进行java class动态替换第3张

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

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

免责声明:文章转载自《利用springloaded进行java class动态替换》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Qt环境搭建wkhtmltopdf 中文参数详解下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

php 常见图片处理函数封装

<?php /** * 常见图像处理函数的封装 */ class Image{ private $info=[]; private $width;//原始图片宽度 private $height;//图片原始高度 private $mime;//图片mime类型 自 PHP 4.3.0 起,getimagesiz...

MyCat 学习笔记 第十二篇.数据分片 之 分片事务处理

1 环境说明 VM 模拟3台MYSQL 5.6 服务器    VM1 192.168.31.187:3307    VM2 192.168.31.212:3307    VM3 192.168.31.150:  3307 MYCAT 1.5 服务部署在宿主机上   MYCAT 192.168.31.207 :8806【SQL执行端口】 / 9066【管理端...

Feign 动态URL 解决记录

Feign中使用动态URL请求 (应当是spring-cloud-starter-openfeign,不知道和一般的feign有何差别) 在spring项目下,假设有这样个Feign的消费接口,原来写死请求百度 @FeignClient(value = "test-service", url="http://www.baidu.com") public i...

testng参数化(提供测试数据)

testng提供测试数据的两个注释:@DataProvide和@Parameter   一、通过testng.xml中设置参数 (实际上testng.xml只是一个名字,可以起任何一个名字,只要是.xml文件,然后文件格式按照testng的文档格式DTD来就可以了) testng.xml中的内容: <?xml version="1.0" encodi...

webService 服务端搭建

  首先,下载CXF,官网(http://cxf.apache.org/),具体位置如下图:      解压后,得到以下目录   下面,我们开始建立工程,在新建的工程lib目录下复制上述lib中的所有文件,特别是endorsed文件夹也要原样复制。 1        WebService的服务器端 1)      创建工程   在eclipse/myEcl...

linux 简介

 linux 介绍(1)Linux根据市场需求不同,基本分为两个方向: 1)图形化界面版:注重用户体验,类似window操作系统,但目前成熟度不够 2)服务器版:没有好看的界面,是以在控制台窗口中输入命令操作系统的,类似于DOS,是我们假设服务器的最佳选择 (2)Linux根据原生程度,又分为两种: 1)内核版本:在Linus领导下的内核小组开发维护的系统...