用 Byte Buddy 重新转换 类
Retransform classes with Byte Buddy
字节好友可以Instrumentation#retransformClasses
已经加载的吗?我想使用 Byte Buddy 的 Java 代理功能,这样我就不必指定 -javaagent
就可以检测 类。例如,使用 Javassist 是可能的。但我正在评估用 Byte Buddy 替换它。
我想在某些方法前后插入一个静态方法调用。如果可能的话,一个简短的例子会很棒!
是的,您可以使用 AgentBuilder
API 来启用重新转换。安装代理后,字节好友将重新转换所有已加载的 classes。您可以像这样启用重新转换:
AgentBuilder builder = new AgentBuilder.Default()
.with(RedefinitionStrategy.RETRANSFORMATION)
.with(InitializationStrategy.NoOp.INSTANCE)
.with(TypeStrategy.Default.REDEFINE);
您可能想知道需要转动的不同开关:
您需要启用重新定义(根据仪器API重新定义或重新转换)。
您需要禁用显式初始化策略。否则,Byte Buddy 会尝试向任何生成的 class 添加显式初始化器,以便在 class 加载后将任何值注入到 class 中。这将改变 HotSpot VM 当前实现不支持的 class 布局。
检测 API 的一个限制是 - 如前所述 - 您不能添加任何新方法。默认情况下,字节好友将任何拦截方法的代码复制到违反此原则的新方法中。通过启用重新定义类型策略,您可以确保 Byte Buddy 永远不会变基方法。
或者,您可以选择不使用 Byte Buddy 的拦截 API,它现在完全取代了被拦截的方法,但使用例如最近添加的 Advice
class 进行手动重新定义.
这样,您可以通过建议您自己的代码来增强现有代码,例如 Advice.to(Foo.class)
,其中引用的 class 的字节代码被插入到被拦截的方法之前和之后:
class Foo {
@Advice.OnMethodEnter
@Advice.OnMethodExit
private static void intercept() {
System.out.println("Before/after");
}
}
您可以在 Advice
的 javadoc 中找到更多信息。
字节好友可以Instrumentation#retransformClasses
已经加载的吗?我想使用 Byte Buddy 的 Java 代理功能,这样我就不必指定 -javaagent
就可以检测 类。例如,使用 Javassist 是可能的。但我正在评估用 Byte Buddy 替换它。
我想在某些方法前后插入一个静态方法调用。如果可能的话,一个简短的例子会很棒!
是的,您可以使用 AgentBuilder
API 来启用重新转换。安装代理后,字节好友将重新转换所有已加载的 classes。您可以像这样启用重新转换:
AgentBuilder builder = new AgentBuilder.Default()
.with(RedefinitionStrategy.RETRANSFORMATION)
.with(InitializationStrategy.NoOp.INSTANCE)
.with(TypeStrategy.Default.REDEFINE);
您可能想知道需要转动的不同开关:
您需要启用重新定义(根据仪器API重新定义或重新转换)。
您需要禁用显式初始化策略。否则,Byte Buddy 会尝试向任何生成的 class 添加显式初始化器,以便在 class 加载后将任何值注入到 class 中。这将改变 HotSpot VM 当前实现不支持的 class 布局。
检测 API 的一个限制是 - 如前所述 - 您不能添加任何新方法。默认情况下,字节好友将任何拦截方法的代码复制到违反此原则的新方法中。通过启用重新定义类型策略,您可以确保 Byte Buddy 永远不会变基方法。
或者,您可以选择不使用 Byte Buddy 的拦截 API,它现在完全取代了被拦截的方法,但使用例如最近添加的 Advice
class 进行手动重新定义.
这样,您可以通过建议您自己的代码来增强现有代码,例如 Advice.to(Foo.class)
,其中引用的 class 的字节代码被插入到被拦截的方法之前和之后:
class Foo {
@Advice.OnMethodEnter
@Advice.OnMethodExit
private static void intercept() {
System.out.println("Before/after");
}
}
您可以在 Advice
的 javadoc 中找到更多信息。