我创建了以下代理,它可以使用ByteBuddy示例LogInterceptor
(只打印被调用方法的名称)来修改每个类并转换每个方法:
public static void main(String[] args) {
ByteBuddyAgent.installOnOpenJDK();
new AgentBuilder.Default()
.rebase(ElementMatchers.any())
.transform((builder, typeDescription) -> builder
.method(ElementMatchers.any())
.intercept(
MethodDelegation
.to(LogInterceptor.class)
.andThen(SuperMethodCall.INSTANCE)
)
)
.installOnByteBuddyAgent();
执行此操作后,我继续调用我的代码,例如:
new JFXPanel()
...初始化JavaFX。但是,我没有看到我的拦截器在JavaFX中打印任何方法。但更糟糕的是,我没有看到ByteBuddy在我的某些类上打印任何方法,尽管它在其中一些方法中完全随机(或者看起来如此)。
我的代理人不应该为每一个类捕获每一个方法吗?这显然不是我想要做的,而是作为一种调试为什么我感兴趣的方法没有被检测的方法。
答案 0 :(得分:0)
似乎LogInterceptor
及其方法的可见性很重要,因此将公共而不是像以前一样的包保护起来会让事情变得有效。但是,这并没有真正解释为什么我的某些方法被正确调用,但无论如何这都是我的问题的答案。
答案 1 :(得分:0)
Byte Buddy确保方法仅在截获的类中被调用,如果它们可见的话。由package-private类声明但没有公共超类声明的公共方法例如对于类是不可见的,因为声明类是调用签名的一部分。否则,这将在运行时导致IllegalAccessException。
如果截获的类没有可见的拦截器方法,则检测失败。您可以向代理注册一个监听器,以使其了解此类情况。
注意:你是对的,Byte Buddy目前认为包私有类型的公共方法即使覆盖另一种公共类型的方法也是不可见的。这不直观,我将改变这种行为。