如何解决如何使用ByteBuddy读取Java类方法注释
示例: 我正在使用字节预算来跟踪方法的进入和退出。在执行此操作时,我需要通过阅读注释@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的方法创建单独的建议来解决问题,如下所示:
@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,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
并用它注释您想要代表自定义值的参数。然后,在绑定过程中提供的绑定器负责解析该值,例如返回一个布尔值,该布尔值指示该方法是否带有注释以及具有什么值。
如果您只想为具有给定批注的方法做事,那么仅将带有批注的方法匹配以应用建议会更有效。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。