javaagent字节码增强浅尝

概述

  • javaagent 技术广泛应用于对代码的增强,比如统计方法执行时间、GC 信息打印、分布式链路跟踪等;
  • 实现方式包括 javassist 和 bytebuddy,bytebuddy 是对 javassist 的改进;
  • 类似于 spring 中的 AOP;

Instrumentation 实现对 main 方法增强

说明:

  • 新建两个项目,一个打包成增强 jar 包,一个写待增强业务代码;
  • 可通过定义注解进行优化;
  • 注意 maven 打包插件;

1)新建一个 maven 项目,引入 pom 依赖,并指定增强类:

<dependencies>
    <!-- javaagent -->
    <dependency>
        <groupId>javassist</groupId>
        <artifactId>javassist</artifactId>
        <version>3.12.1.GA</version>
        <type>jar</type>
    </dependency>
</dependencies>

<build>
    <plugins>
        <!-- 测试javaagent相关 -->
        <plugin>
            <!-- 打普通的jar包 -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <!-- 打包配置 -->
                <archive>
                    <manifestEntries>
                        <Project-name>${project.name}</Project-name>
                        <Project-version>${project.version}</Project-version>
                        <!-- main方法之前需要处理的类 -->
                        <Premain-Class>com.firechou.test.javaagent.FireAgent</Premain-Class>
                    </manifestEntries>
                </archive>
                <skip>true</skip>
            </configuration>
        </plugin>
    </plugins>
</build>

注意插件中 Premain-Class 指定的是增强类。

2)新建代理类,编写增强逻辑

public class FireAgent {

    /**
     * 在Instrumentation中有对应的说明:当jvm以代理类的方式启动时,Instrumentation的实例将传递给premain方法
     * @param args
     * @param instrumentation
     */
    public static void premain(String args, Instrumentation instrumentation){
        System.out.println("agent premain(), args: " + args);
    }

}

3) 打包成 jar
执行打包命令:
javaagent字节码增强浅尝_第1张图片
注意:不要执行 Plugins》jar》jar:jar 命令,会提示找不到目标类。
生成增强 jar 包如下:
javaagent字节码增强浅尝_第2张图片

4)在另一个项目中,新建业务代码类,即被增强的逻辑

public class FireAgentMainTest {
    public static void main(String[] args) {
        System.out.println("hello world");
    }
}

添加 JVM 运行参数:

-javaagent:test-javaagent/target/test-javaagent-1.0-SNAPSHOT.jar=name=jar&age=33

javaagent字节码增强浅尝_第3张图片
运行结果:

agent premain(), args: name=jar&age=33
hello world

你可能感兴趣的:(#,SkyWalking,javaagent,字节码增强,埋点,javassist,bytebuddy)