Byte Buddy动态代理与运行时字节码生成
讲解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用此)