hz90 / java-base-knowledge

0 stars 0 forks source link

java 探针实现 #3

Open hz90 opened 5 years ago

hz90 commented 5 years ago

package com.aop;

import java.lang.instrument.Instrumentation;

public class Agent { public static void premain(String agent, Instrumentation instrumentation) { System.out.println("execute start"); instrumentation.addTransformer(new AOPIml()); System.out.println("execute end"); } }

package com.aop;

import java.io.ByteArrayInputStream; import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.security.ProtectionDomain;

import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod;

public class AOPIml implements ClassFileTransformer { public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { byte[] byteCodes = classfileBuffer;

    //可以过滤class
    if ("com/aop/TestClassAop".equals(className)) {
        System.out.println("bytecode add......");
        try {
            ClassPool classPool = ClassPool.getDefault();
            CtClass ctClass = classPool.makeClass(new ByteArrayInputStream(
                    classfileBuffer));
            CtMethod[] methods = ctClass.getDeclaredMethods();
            //也可以过滤方法
            for (CtMethod method : methods) {
                method.addLocalVariable("startTime", CtClass.longType);
                method.insertBefore("startTime = System.nanoTime();");
                method.insertAfter("System.out.println(\"Execution method: "+method.getName()
                        + "(nano sec): \"+ (System.nanoTime() - startTime) );");
            }
            byteCodes = ctClass.toBytecode();
            ctClass.detach();
            System.out.println("bytecode add complete.");
        } catch (Throwable ex) {
            System.out.println("Exception: " + ex);
            ex.printStackTrace();
        }
    }
    return byteCodes;
}

}


package com.aop;

public class TestClassAop { public TestClassAop() { System.out.println("i am a constructor"); } public void main() { System.out.println("this is TestClassAop main"); test();

}
public  void test() {
    System.out.println("this is TestClassAop test");
}

}

package com.aop;

public class TestClient { public static void main(String[] args) { TestClassAop t=new TestClassAop(); t.main(); } }


打包成jar ①用jar -xvf aop.jar解开 编辑META-INF/MANIFEST.MF文件 Manifest-Version: 1.0 premain-class: com.aop.Agent Class-Path: javassist-3.21.0-GA.jar 最后必须有一行空行

②然后打包 jar cvfm aops.jar META-INF/MANIFEST.MF com/aop/*.class

③然后运行 java -javaagent:aops.jar com.aop.TestClient 以下为输出的结果 execute start execute end bytecode add...... bytecode add complete. i am a constructor this is TestClassAop main this is TestClassAop test Execution method: test(nano sec): 1000057 Execution method: main(nano sec): 3061073