写在前面
本文看下如何通过javassist结合hotswap在运行期动态修改方法的返回值。
1:代码
- 要修改的代码
public class ApiTest {
public String m1(String info) {
return "info is: " + info;
}
}
- javasssit代码
package com.dahuyou.javassist.huohuo;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.util.HotSwapper;
public class GenerateClazzMethod {
public static void main(String[] args) throws Exception {
ApiTest apiTest = new ApiTest();
new Thread(() -> {
while (true){
System.out.println(apiTest.m1("生活的意义到底是什么???"));
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
// 监听 8000 端口,在启动参数里设置
// java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
HotSwapper hs = new HotSwapper(8000);
ClassPool pool = ClassPool.getDefault();
CtClass ctClass = pool.get(ApiTest.class.getName());
// 获取方法
CtMethod ctMethod = ctClass.getDeclaredMethod("m1");
// 重写方法
ctMethod.setBody("{ return \"the input info is: \" + info; }");
// 加载新的类
System.out.println(":: 执行HotSwapper热插拔,增加【the input】!");
hs.reload(ApiTest.class.getName(), ctClass.toBytecode());
}
}
需要配置vm参数-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000
:
运行一下:
技术点:
1:需要在vm中配置-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000,hotswp需要连接到端口执行操作
2:HotSwapper负责在运行期加载新的字节码到jvm中完成热更新,所以,这里我们只是通过javassist来生成字节码而已,热更新和javassist本质上是没有关系的,只要有新的字节码就可以通过hotswapper的reload方法来完成热更新
3:热更新依赖于hotswap的reload方法
写在后面
针对hotswap实现热更新,我们也可以应用到平时的开发以及测试工作中。比如测试发现了一个bug,你就可以使用这种方式来快速让修改的代码生效,从而快速验证。