java替换的程序,如何在java中运行的应用程序中替换类?

本文通过一个示例展示了如何使用自定义类加载器实现Java程序的热更新功能,类似于Tomcat对web应用的动态重载。Test1类在运行时被动态加载并调用,当源代码更改并重新编译后,可以看到输出的Hello!变为Hello!!!,说明类已成功更新。这种方法利用了Java的类加载机制,确保新版本的类替换旧版本,并且旧的类会被垃圾收集器回收。
摘要由CSDN通过智能技术生成

这是一个工作测试.每5秒Test.main()从文件系统重新加载test.Test1.class并调用Test1.hello()

package test;

public class Test1 {

public void hello() {

System.out.println("Hello !");

}

}

public class Test {

static class TestClassLoader extends ClassLoader {

@Override

public Class> loadClass(String name) throws ClassNotFoundException {

if (name.equals("test.Test1")) {

try {

InputStream is = Test.class.getClassLoader().getResourceAsStream("test/Test1.class");

byte[] buf = new byte[10000];

int len = is.read(buf);

return defineClass(name, buf, 0, len);

} catch (IOException e) {

throw new ClassNotFoundException("", e);

}

}

return getParent().loadClass(name);

}

}

public static void main(String[] args) throws Exception {

for (;;) {

Class cls = new TestClassLoader().loadClass("test.Test1");

Object obj = cls.newInstance();

cls.getMethod("hello").invoke(obj);

Thread.sleep(5000);

}

}

}

运行.然后更改并重新编译Test1

System.out.println("Hello !!!");

而测试正在运行.您将看到Test1.hello输出更改

...

Hello !

Hello !

Hello !!!

Hello !!!

这就是Tomcat如何重新加载webapps.它为每个webapp都有一个单独的ClassLoader,并在新的ClassLoader中加载一个新版本.旧的是GCed就像任何Java对象以及旧类一样.

请注意,我们使用TestClassLoader加载Test1,并通过反射调用其第一个方法.但是所有Test1依赖项将被隐式加载Test1类加载器,即所有Test1应用程序将被JVM加载到TestClassLoader中.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值