首页 > 代码库 > 基于Instrumentation的JAVA代码热替换

基于Instrumentation的JAVA代码热替换

理类用来获取 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
...