[英]How to read a Java class method annotation with ByteBuddy
How can I read Java class method annotation at runtime with ByteBuddy?如何在运行时使用 ByteBuddy 读取 Java 类方法注释?
Example: I am using bytebuddy to track method enter and exit.示例:我正在使用 bytebuddy 来跟踪方法进入和退出。 While doing this, I need to know whether a method is unit test by reading the annotation @Test.
这样做时,我需要通过阅读注释@Test 来知道一个方法是否是单元测试。
@Test
public void getBuildByAuthor() {
.
.
}
Here is a sample on how I am recording enter/exit of methods.这是关于我如何记录方法的进入/退出的示例。
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);
}
Update: I solved the problem by creating separate Advice for methods with annotation @Test as follows:更新:我通过为带有注释 @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);
}
I understand it that you would like to read an annotation from your advice?我知道您想从您的建议中阅读注释? You'd need to register a custom binding that produces this value as its result.
您需要注册一个生成此值作为结果的自定义绑定。
Advice
allows this by a configuration: Advice
通过配置允许这样做:
Advice.withCustomMapping().bind(MyAnnotation.class, ...).to(...)
All you need to do is to define an annotation yourself, set Retention.RUNTIME
for it and annotate the parameter you'd like to represent your custom value with it.您需要做的就是自己定义一个注释,为其设置
Retention.RUNTIME
并用它来注释您想要表示自定义值的参数。 The binder that is supplied during the binding is then responsible to resolve this value, for example to return a boolean that indicates if the method is annotated and with what values.在绑定期间提供的绑定器然后负责解析这个值,例如返回一个布尔值,指示该方法是否被注释以及具有什么值。
If you only want to do things for methods with a given annotation, it would however be more efficient to only match methods with the annotations to apply the advice.如果您只想为具有给定注释的方法做一些事情,那么仅将方法与注释匹配以应用建议会更有效。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.