Java 用字节重发类

Java 用字节重发类,java,instruments,javaagents,byte-buddy,Java,Instruments,Javaagents,Byte Buddy,Byte Buddy是否能够插装#重新传输已加载的类?我想使用Byte Buddy的Java代理特性,这样我就不必指定-javaagent来插入类。这是可能的,例如使用Javassist。但我正在评估用Byte Buddy替换它 我想在某些方法之前和之后插入一个静态方法调用。如果这是可能的,一个简短的例子将是伟大的 是的,您可以使用AgentBuilderAPI来启用重新传输。安装代理后,Byte Buddy将重新传输所有已加载的类。您可以这样启用重新传输: AgentBuilder build

Byte Buddy是否能够
插装#重新传输已加载的类
?我想使用Byte Buddy的Java代理特性,这样我就不必指定
-javaagent
来插入类。这是可能的,例如使用Javassist。但我正在评估用Byte Buddy替换它


我想在某些方法之前和之后插入一个静态方法调用。如果这是可能的,一个简短的例子将是伟大的

是的,您可以使用
AgentBuilder
API来启用重新传输。安装代理后,Byte Buddy将重新传输所有已加载的类。您可以这样启用重新传输:

AgentBuilder builder = new AgentBuilder.Default()    
  .with(RedefinitionStrategy.RETRANSFORMATION)
  .with(InitializationStrategy.NoOp.INSTANCE)
  .with(TypeStrategy.Default.REDEFINE);
您可能想知道需要打开哪些不同的开关:

  • 您需要启用重新定义(根据检测API重新定义或重新传输)

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

  • 正如前面提到的,检测API的一个限制是不能添加任何新方法。默认情况下,Byte Buddy将任何被截获方法的代码复制到一个新方法中,该方法违反了此原则。通过启用重新定义类型策略,您可以确保Byte Buddy永远不会对方法进行重定

  • 或者,您可以选择不使用Byte Buddy的截取API,该API现在完全替代了被截取的方法,而是使用最近添加的
    Advice
    类进行手动重新定义

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

    class Foo {
      @Advice.OnMethodEnter
      @Advice.OnMethodExit
      private static void intercept() {
        System.out.println("Before/after");
      }
    }
    
    您可以在javadoc中找到有关
    建议的更多信息