分类: Java开发

基于 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 方法的调用就全转到 新类上了。

Recent Posts

Docker 容器非 root 用户监听 80 端口

起因是基于 CentOS 的 …

2 年 之前

基于 Docker 定时打印文件

先说背景,喷墨打印机有个很大的…

3 年 之前

Java 运行时反射获取来自继承的泛型

背景 正常情况下 Java 的…

3 年 之前

Java 基于 ByteBuddy 重写系统当前时间

背景 一般单元测试时总会有些代…

3 年 之前

华硕 B450F-Gaming 主板 I211-AT 网卡驱动安装

事情起因是买了块华硕的 ROG…

3 年 之前

PHP 安装 Memcached 扩展

登录服务器挨步执行: # su…

4 年 之前