基于 ByteBuddy 运行时动态修改字节码

简介

Byte Buddy 是一个字节码生成与操作库。它无需编译器,能够在Java程序运行时创建与修改 class 文件。

目标

已有类文件:

public static class Log {
    public static void log(String a) {

        System.out.println("Log: " + a);
    }
}

目标是将所有 Log 类中对 log 方法的调用全转到 log4j 上。

准备

修改 pom.xml 添加依赖:

<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy</artifactId>
    <version>1.8.0</version>
</dependency>
<dependency>
    <groupId>net.bytebuddy</groupId>
    <artifactId>byte-buddy-agent</artifactId>
    <version>1.8.0</version>
</dependency>

模块加载及字节码修改

ByteBuddyAgent.install();
new ByteBuddy().redefine(Log.class)
               .method(ElementMatchers.named("log"))
               .intercept(MethodDelegation.to(Log4j.class))
               .make()
               .load(Thread.currentThread().getContextClassLoader(), ClassReloadingStrategy.fromInstalledAgent());

重新定义的实现类如下:

public static class Log4j {
    public static void log(String a) {
        System.err.println("Log4j: " + a);
    }
}

注意代理类要和原实现类的方法声明保持一致

All Done !

此时就会发现所有对 Log 方法的调用就全转到 新类上了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注