1

Byte Buddy 是否能够Instrumentation#retransformClasses已经加载?我想使用 Byte Buddy 的 Java 代理功能,这样我就不必指定-javaagent能够检测类。例如,使用 Javassist 可以做到这一点。但我正在评估用 Byte Buddy 替换它。

我想在某些方法之前和之后插入一个静态方法调用。如果可能的话,一个简短的例子会很棒!

4

1 回答 1

3

是的,您可以使用AgentBuilderAPI 启用重新转换。安装代理后,Byte Buddy 将重新转换所有已加载的类。您可以像这样启用重新转换:

AgentBuilder builder = new AgentBuilder.Default()    
  .with(RedefinitionStrategy.RETRANSFORMATION)
  .with(InitializationStrategy.NoOp.INSTANCE)
  .with(TypeStrategy.Default.REDEFINE);

您可能想知道需要转动的不同开关:

  1. 您需要启用重新定义(根据检测 API 重新定义或重新转换)。

  2. 您需要禁用显式初始化策略。否则,Byte Buddy 会尝试将显式初始化程序添加到任何生成的类中,以便在加载后将任何值注入到类中。这将改变 HotSpot VM 的当前实现不支持的类布局。

  3. 如前所述,检测 API 的一个限制是您不能添加任何新方法。默认情况下,Byte Buddy 会将任何拦截方法的代码复制到一个违反此原则的新方法中。通过启用重新定义类型策略,您可以确保 Byte Buddy 永远不会重新定义方法。

或者,您可以选择不使用 Byte Buddy 的拦截 API,它现在完全替换被拦截的方法,但使用例如最近添加的Advice类进行手动重新定义。

这样,您可以通过建议您自己的代码来增强现有代码,例如Advice.to(Foo.class)在被拦截的方法之前和之后插入引用类的字节码:

class Foo {
  @Advice.OnMethodEnter
  @Advice.OnMethodExit
  private static void intercept() {
    System.out.println("Before/after");
  }
}

您可以在 javadoc 中找到更多信息Advice

于 2016-03-14T08:57:23.237 回答