使用 ByteBuddy 检测一组接口的所有实现
Instrument all implementations of a set of interfaces with ByteBuddy
背景:我想使用 LogInterceptor(仅记录方法被调用)检测一组接口(在同一包内)的所有实现。因此我用byte-buddy写了一个javaagent。总的来说,这工作正常,但我正在努力寻找一组接口的所有实现。
假设我们在一个包my.company.api中有一组Java接口,那么我尝试了以下方式:
public static void premain(String arguments, Instrumentation instrumentation) {
new AgentBuilder.Default()
.ignore(ElementMatchers.isInterface())
.ignore(ElementMatchers.isEnum())
.type(ElementMatchers.nameMatches("my\.company\.api\..*"))
.transform(new AgentBuilder.Transformer() {
@Override
public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, ClassLoader classloader) {
return builder
.method(ElementMatchers.isPublic())
.intercept(MethodDelegation.to(LogInterceptor.class));
}
}).installOn(instrumentation);
}
我对 byte-buddy 很陌生,也许有人可以给我提示我做错了什么。
首先,您没有正确链接忽略匹配器;应该是:
.ignore(isInterface().or(isEnum()))
至于匹配接口,可以试试hasSuperType
匹配器。如果您尝试匹配给定包的接口,您可以尝试:
hasSuperType(nameStartsWith("my.company.api.").and(isInterface()))
与正则表达式相比,使用前缀匹配器效率更高。
背景:我想使用 LogInterceptor(仅记录方法被调用)检测一组接口(在同一包内)的所有实现。因此我用byte-buddy写了一个javaagent。总的来说,这工作正常,但我正在努力寻找一组接口的所有实现。
假设我们在一个包my.company.api中有一组Java接口,那么我尝试了以下方式:
public static void premain(String arguments, Instrumentation instrumentation) {
new AgentBuilder.Default()
.ignore(ElementMatchers.isInterface())
.ignore(ElementMatchers.isEnum())
.type(ElementMatchers.nameMatches("my\.company\.api\..*"))
.transform(new AgentBuilder.Transformer() {
@Override
public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, ClassLoader classloader) {
return builder
.method(ElementMatchers.isPublic())
.intercept(MethodDelegation.to(LogInterceptor.class));
}
}).installOn(instrumentation);
}
我对 byte-buddy 很陌生,也许有人可以给我提示我做错了什么。
首先,您没有正确链接忽略匹配器;应该是:
.ignore(isInterface().or(isEnum()))
至于匹配接口,可以试试hasSuperType
匹配器。如果您尝试匹配给定包的接口,您可以尝试:
hasSuperType(nameStartsWith("my.company.api.").and(isInterface()))
与正则表达式相比,使用前缀匹配器效率更高。