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:
public class TestMain { public static void main(String[]args){ People people = new People(); people.sayHello(); } }
people类:
public classPeople { public voidsayHello(){ System.out.println("hello !!!!"); } }
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路径;
运行结果: