CodeWalk

Byte Buddy动态代理与运行时字节码生成

作者:孤独的心 · 2026-05-30 12:55

讲解Byte Buddy框架的高级特性,包括动态创建类、方法拦截(MethodDelegation)、注解驱动的Agent构建、以及与JDK动态代理和CGLIB的对比。

回答

孤独的心

1. Byte Buddy核心能力

  • 创建类new ByteBuddy().subclass(Class)
  • 修改类redefine/rebase(配合Java Agent)
  • 方法拦截intercept(MethodDelegation)

2. 方法拦截示例

// 1. 拦截所有方法
String result = new ByteBuddy()
    .subclass(Foo.class)
    .method(ElementMatchers.any())
    .intercept(MethodDelegation.to(BarInterceptor.class))
    .make()
    .load(getClass().getClassLoader())
    .getLoaded()
    .newInstance()
    .foo();

// 2. 拦截器
public class BarInterceptor {
    @RuntimeType
    public static Object intercept(@Origin Method method, 
                                   @AllArguments Object[] args,
                                   @SuperCall Callable<?> callable) throws Exception {
        System.out.println("Before: " + method.getName());
        try {
            return callable.call();  // 调用原方法
        } finally {
            System.out.println("After: " + method.getName());
        }
    }
}

3. Agent结合

public class MyAgent {
    public static void premain(String args, Instrumentation inst) {
        new AgentBuilder.Default()
            .type(ElementMatchers.named("com.example.TargetClass"))
            .transform((builder, type, classLoader, module) ->
                builder.method(ElementMatchers.named("execute"))
                    .intercept(MethodDelegation.to(TimingInterceptor.class))
            ).installOn(inst);
    }
}

4. 对比其他代理方案 | 特性 | JDK动态代理 | CGLIB | Byte Buddy | |------|------|------|------| | 实现 | 接口代理 | 类代理(继承) | 类代理 + 字节码重定义 | | 性能 | 中(反射调用) | 高(FastClass) | 最高(直接生成的字节码) | | 灵活性 | 仅支持接口 | 类和方法 | 任意修改(add/rename/delete) | | 易用性 | 简单 | 中等 | 中等(DSL风格) | | 依赖体积 | 无 | asm.jar~50KB | byte-buddy.jar~400KB |

5. 高级特性

  • @BindingPriority:多个拦截方法的优先级
  • @Pipe:管道调用链
  • @DefaultCall:调用默认方法
  • @SuperMethod:访问父类方法
  • StubMethod:返回默认值(Mockito用此)