理类用来获取 Instrumentation 实例
package com.codeconch.util; import java.lang.instrument.Instrumentation; public class Monitor { private static Instrumentation instrumentation; public static void premain(String args, Instrumentation inst) { instrumentation = inst; } public static Instrumentation getInstrumentation(){ return instrumentation; } }
将这个类打成AgentJAR包monitor.jar
配置MANIFEST.MF
Manifest-Version: 1.0
Premain-Class: com.codeconch.util.Monitor
Can-Redefine-Classes: true
/** * * @author 赵聪慧 * 2014-3-31下午5:21:12 */ public class Test { <span style="white-space:pre"> </span>static int i=5; <span style="white-space:pre"> </span>private int a=2; <span style="white-space:pre"> </span>public int geta(){ <span style="white-space:pre"> </span>return a+i; <span style="white-space:pre"> </span>} }
将Test类编译好放到另一个目录 这里放到了d:
将Test类中的代码改为
/** * * @author 赵聪慧 * 2014-3-31下午5:21:12 */ public class Test { <span style="white-space:pre"> </span>static int i=5; <span style="white-space:pre"> </span>private int a=2; <span style="white-space:pre"> </span>public int geta(){ <span style="white-space:pre"> </span>return a*i; <span style="white-space:pre"> </span>} }
加agent参数 运行launch
-javaagent:D:\monitor.jar
public static void main(String args[]) throws InvalidProtocolBufferException{ Test test=new Test(); while(true){ try { System.out.println(test.geta()); byte[] bytesFromFile = FileUtil.getBytesFromFile("D:/Test.class"); Monitor.getInstrumentation().redefineClasses(new ClassDefinition(Test.class,bytesFromFile)); Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnmodifiableClassException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
输出
10 7 7 7 ...
基于Instrumentation的JAVA代码热替换,布布扣,bubuko.com
时间: 2024-10-13 11:56:26