Byte Buddy 是一个用于运行时生成 Java 类的库。它的功能不仅限于创建代理类,而且代理类的创建是一个明显的用例。
假设,我们正在处理以下代码:
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation { }
@MyAnnotation
class Foo {
@MyAnnotation
public void bar() { }
}
然后我们可以在运行时创建一个覆盖bar 方法的子类。 bar 方法的重写实现被实现为简单地调用其超级实现:
Class<?> runtimeType = new ByteBuddy()
.withAttribute(TypeAttributeAppender.ForSuperType.INSTANCE)
.withDefaultMethodAttributeAppender(MethodAttributeAppender.ForInstrumentedMethod.INSTANCE)
.subclass(Foo.class)
.method(named("bar")).intercept(SuperMethodCall.INSTANCE)
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
使用上面的运行时类,我们现在可以验证结果类型:
assertNotEquals(Foo.class, runtimeType);
assertThat(runtimeType.isAnnotationPresent(MyAnnotation.class)), is(true));
assertThat(runtimeType.getDeclaredMethod("bar").isAnnotationPresent(MyAnnotation.class)), is(true));
尽管有子类,但类型和方法都由MyAnnotation 注释。通过调用getDeclaredMethod,我们进一步验证子类实际上定义了一个新方法。
披露:我是 Byte Buddy 的作者,我想为这个问题提供一个答案,这个问题在稍微更具体的上下文中经常在 SO 上被问到。此外,我想借此机会为 Byte Buddy 创建一个 SO 标签。