示例作用

向已存在的方法中添加其它指令

新建项目

配置文件指定premainclass

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.6.2</version>
        <configuration>
          <source>1.8</source>
          <target>1.8</target>
          <encoding>UTF-8</encoding>
        </configuration>

      </plugin>

      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>3.0.0</version>
        <executions>
          <execution>
            <phase>package</phase>
            <goals>
              <goal>shade</goal>
            </goals>
            <configuration>
              <transformers>
                <transformer
                  implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                  <manifestEntries>
                    <Main-Class>com.kevin.agent.Application</Main-Class>
                    <Premain-Class>com.kevin.agent.MyAgent</Premain-Class>
                  </manifestEntries>
                </transformer>
              </transformers>
            </configuration>
          </execution>
        </executions>
      </plugin>

添加asm依赖


  <dependencies>
    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm</artifactId>
      <version>7.3</version>
    </dependency>

    <dependency>
      <groupId>org.ow2.asm</groupId>
      <artifactId>asm-tree</artifactId>
      <version>7.3</version>
    </dependency>
  </dependencies>

MyAgent

新增class com.kevin.agent.MyAgent

public class MyAgent {

    public static void premain(String agentArgs, Instrumentation inst) {


        System.out.println("premain");
        inst.addTransformer(new MyTransformer());
        System.out.println("premain end");
    }

    static class MyTransformer implements ClassFileTransformer, Opcodes {
        public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined,
                                ProtectionDomain protectionDomain, byte[] classfileBuffer) throws


                                                                                           IllegalClassFormatException {

            if (className.startsWith("java") ||
                className.startsWith("javax") ||
                className.startsWith("jdk") ||
                className.startsWith("sun") ||
                className.startsWith("com/sun") ||
                className.startsWith("org/example")) {
                // Skip JDK classes and profiler classes
                return null;
            }

            ClassReader cr = new ClassReader(classfileBuffer);
            ClassNode classNode = new ClassNode(ASM7);
            cr.accept(classNode, ClassReader.SKIP_FRAMES);

            for (MethodNode methodNode : classNode.methods) {
                for (AbstractInsnNode node : methodNode.instructions.toArray()) {
                    System.out.println(node.getOpcode());
                    if (node.getOpcode() == INVOKEVIRTUAL) {
                        InsnList instrumentation = new InsnList();
                        instrumentation.add(new FieldInsnNode(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;"));
                        instrumentation.add(new LdcInsnNode("Hello, Instrumentation!"));
                        instrumentation
                                .add(new MethodInsnNode(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false));

                        methodNode.instructions.insert(node, instrumentation);
                    }
                }
            }

            ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
            classNode.accept(cw);
            return cw.toByteArray();
        }
    }
}

启动类

public class Application {

    public static void main(String []args){
        System.out.println("Start main");

        System.out.println("Stop main");
    }
}

启动命令

java -javaagent:target/jvm-agent-1.0-SNAPSHOT.jar  -jar target/jvm-agent-1.0-SNAPSHOT.jar