[英]How to read a Java class method annotation with ByteBuddy
如何在运行时使用 ByteBuddy 读取 Java 类方法注释?
示例:我正在使用 bytebuddy 来跟踪方法进入和退出。 这样做时,我需要通过阅读注释@Test 来知道一个方法是否是单元测试。
@Test
public void getBuildByAuthor() {
.
.
}
这是关于我如何记录方法的进入/退出的示例。
public class MethodTracer {
@Advice.OnMethodEnter(inline = false)
public static Item enter(@Advice.Origin("#t") String type,
@Advice.Origin("#m") String method,
@Advice.Origin("#s") String signature)
{
//TODO: is this Unit test method identified by @Test ?
return Tracer.enter(type, method, signature);
}
@Advice.OnMethodExit(inline = false, onThrowable = Throwable.class)
public static void exit(@Advice.Enter Item item) {
Tracer.exit(item);
}
}
@Override
public void instrument(Instrumentation instrumentation) {
final Advice methodAdvice = Advice.to(MethodTracer.class);
final Advice constructorAdvice = Advice.to(ConstructorTracer.class);
ResettableClassFileTransformer agent = new AgentBuilder.Default()
.with(new TracerLogger())
.type(ElementMatchers.nameStartsWith("com.examples."))
.transform(new AgentBuilder.Transformer() {
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
builder = builder.visit(new AsmVisitorWrapper.ForDeclaredMethods().method(ElementMatchers.isMethod(), methodAdvice));
builder = builder.visit(new AsmVisitorWrapper.ForDeclaredMethods().constructor(ElementMatchers.isConstructor(), constructorAdvice));
return builder;
}
})
.installOn(instrumentation);
}
更新:我通过为带有注释 @Test 的方法创建单独的 Advice 解决了这个问题,如下所示:
@Override
public void instrument(Instrumentation instrumentation) {
final Advice methodAdvice = Advice.to(MethodTracer.class);
final Advice testMethodAdvice = Advice.to(TestMethodTracer.class);
final Advice constructorAdvice = Advice.to(ConstructorTracer.class);
final Advice testConstructorAdvice = Advice.to(TestConstructorTracer.class);
ResettableClassFileTransformer agent = new AgentBuilder.Default()
.with(new TracerLogger())
.type(ElementMatchers.nameStartsWith("com.examples."))
.transform(new AgentBuilder.Transformer() {
@Override
public DynamicType.Builder<?> transform(DynamicType.Builder<?> builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) {
builder = builder.visit(new AsmVisitorWrapper.ForDeclaredMethods().method(ElementMatchers.isMethod().and(ElementMatchers.isAnnotatedWith(Test.class)), testMethodAdvice));
builder = builder.visit(new AsmVisitorWrapper.ForDeclaredMethods().method(ElementMatchers.isMethod().and(ElementMatchers.not(ElementMatchers.isAnnotatedWith(Test.class))), methodAdvice));
builder = builder.visit(new AsmVisitorWrapper.ForDeclaredMethods().constructor(ElementMatchers.isConstructor().and(ElementMatchers.isAnnotatedWith(Test.class)), testConstructorAdvice));
builder = builder.visit(new AsmVisitorWrapper.ForDeclaredMethods().constructor(ElementMatchers.isConstructor().and(ElementMatchers.not(ElementMatchers.isAnnotatedWith(Test.class))), constructorAdvice));
return builder;
}
})
.installOn(instrumentation);
}
我知道您想从您的建议中阅读注释? 您需要注册一个生成此值作为结果的自定义绑定。 Advice
通过配置允许这样做:
Advice.withCustomMapping().bind(MyAnnotation.class, ...).to(...)
您需要做的就是自己定义一个注释,为其设置Retention.RUNTIME
并用它来注释您想要表示自定义值的参数。 在绑定期间提供的绑定器然后负责解析这个值,例如返回一个布尔值,指示该方法是否被注释以及具有什么值。
如果您只想为具有给定注释的方法做一些事情,那么仅将方法与注释匹配以应用建议会更有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.