javaagent字节码增强浅尝

概述

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

Instrumentation 实现对 main 方法增强

说明:

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

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

bash 复制代码
<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)新建代理类,编写增强逻辑

java 复制代码
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

执行打包命令:

注意:不要执行 Plugins》jar》jar:jar 命令,会提示找不到目标类。

生成增强 jar 包如下:

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

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

添加 JVM 运行参数:

bash 复制代码
-javaagent:test-javaagent/target/test-javaagent-1.0-SNAPSHOT.jar=name=jar&age=33

运行结果:

bash 复制代码
agent premain(), args: name=jar&age=33
hello world
相关推荐
逆风就重开1 个月前
数据埋点系列 12|数据驱动决策的组织变革:从传统到数据驱动的蜕变之路
大数据·埋点·数据埋点
爱桥代码的程序媛1 个月前
HamronyOS开发5.0【埋点】方案讲解
程序员·移动开发·harmonyos·鸿蒙·openharmony·埋点·鸿蒙开发
逆风就重开1 个月前
数据埋点系列 6|数据驱动决策的实际应用:从理论到实践
大数据·数据分析·埋点·数据埋点
aaaak_1 个月前
用户行为埋点分析 第一章
埋点·行为分析
西凉的悲伤2 个月前
Javassist 修改 jar 包里的 class 文件
java·jar·javassist
Muroidea4 个月前
使用javassist对类做字节码增强
java·aop·javassist·bytecode
QX_Java_Learner4 个月前
MyBatis——使用 Javassit 在内存中生成类
mybatis·javassist
_抱歉打扰了6 个月前
Flink实时数仓之用户埋点系统(一)
大数据·flink·埋点
Z3r4y6 个月前
【Java】小白友好的Javassist源代码级别常用API学习笔记
java·jvm·web·ctf·字节码·javassist
技术路上的苦行僧6 个月前
SpringCloud(20)之Skywalking Agent原理剖析
springcloud·skywalking·java agent·字节码增强·bytebuddy