作用
Java Instrument指的是可以用独立于应用程序之外的代理程序来监测和协助运行在JVM上的应用程序,包括但不限于获取JVM运行时状态,替换和修改类定义。
使用方法
Java SE5及以后的版本,可以在一个普通Java程序运行时,通过-javaagent参数制定一个特定的jar文件(包含Instrumentation代理)来启动Instrumentation的代理程序。
代理类必须提供一个public static void premain(String args, Instrumentation inst)或public static void premain(String args)方法。
在命令行启动该代理jar时,VM会根据manifest中指定的代理类,使用与main类相同的系统类加载器加载代理类,在执行main方法前执行premain()方法。
简单示例
一个简单的main类
main:
public class TestMain {
public static void main(String[]args){
People people = new People();
people.sayHello();
}
}
people类:
public classPeople {
public voidsayHello(){
System.out.println("hello !!!!");
}
}
agent实例
public classMyAgent {
/**
* 该方法是一个类作为agent类必备的
* @paramagentArgs
* @paraminst
*/
public static void premain(String agentArgs,Instrumentation inst){
//加入ClassFileTransfomer
inst.addTransformer(new PeopleClassFileTransformer());
}
}
PeopleClassFileTransformer类,主要通过javassist修改sayHello方法字节码
public class PeopleClassFileTransformerimplementsClassFileTransformer {
/**
* 通过javassist修改字节码
* @paramloader
* @paramclassName
* @paramclassBeingRedefined
* @paramprotectionDomain
* @paramclassfileBuffer
* @return
* @throws IllegalClassFormatException
*/
@Override
public byte[]transform(ClassLoader loader,String className,Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throwsIllegalClassFormatException {
System.out.println("load class:" + className);
if("com/yao/intrumentation/People".equals(className)) {
try{
//通过javassist修改sayHello方法字节码
CtClass ctClass= ClassPool.getDefault().get(className.replace('/','.'));
CtMethod sayHelloMethod=ctClass.getDeclaredMethod("sayHello");
sayHelloMethod.insertBefore("System.out.println(\"before sayHello----\");");
sayHelloMethod.insertAfter("System.out.println(\"after sayHello----\");");
return ctClass.toBytecode();
} catch (NotFoundException e) {
e.printStackTrace();
} catch (CannotCompileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return classfileBuffer;
}
}
然后编写MAINIFEST.MF文件如下:
Manifest-Version: 1.0
Premain-Class:: com.yao.intrumentation.MyAgent
Created-By: 1.8.0_121
打包MyAgent文件成MyAgent.jar
输出
在ideal运行配置界面中VM options输入-javaagent:E:/Java_Web/JavaSPI-master/target/classes/myagent.jar,即MyAgent.jar路径;
运行结果: