gpt4 book ai didi

annotations - 字节码注入(inject)发生在哪里?

转载 作者:行者123 更新时间:2023-12-01 10:55:44 24 4
gpt4 key购买 nike

动机

我有一个 SomeObject.java文件:

class SomeObject {
String name;
}

编译它会创建一个包含字节码的 SomeObject.class文件。
0xCAFEBABE...

如果我们在 JVM 上使用 SomeObject,它会被当前的类加载器加载并且一切正常。

现在让我们假设我想要一些动态代码生成。我可以编写我的自定义注释
@Target(ElementType.TYPE)
public @interface Data {
...
}

并将其作为修饰符添加到类声明中:
@Data
class SomeObject {
String name;
}

我也可以使用 @Retention(RetentionPolicy.RUNTIME) 将其保留在运行时。 :
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Data {
...
}

问题

用于字节码注入(inject)的注解在哪里?当使用适当的运行时保留注释加载类时,类加载器是否注入(inject)字节码,如下图所示:
source -(compile)-> bytecode -(classloader bytecode injection)-> injected bytecode -(classloading)-> JVM loaded bytecode   

最佳答案

是的,可以让您的自定义类加载器加载一个类并通过字节码操作工具,例如 JavassistASM执行修改,不是将类文件中的字节码加载到内存中,而是将修改后的字节码加载到内存中。
尽管有更简单(我认为更好)的方法来做到这一点。

注释处理器工具 (APT)

从 Java 6 开始,您拥有 APT它允许您进入编译过程(通过 javac 中的 -processor 参数)。使用 APT,您可以访问代码的 AST(抽象语法树),并且可以在使用 javax.lang.model 进行编译时直接进行修改。 .这意味着将生成您的类文件并进行所需的修改。

在这种情况下,链将类似于:
source -(compile and performs modifications at model level)-> bytecode already modified - regular class loader -> loads class into memory
编译后处理

可以使用的另一种方法是在编译后作为编译后过程执行字节码注入(inject)。在这种情况下,您使用字节码修改工具(同样是 javassist、asm 等),它可以在找到所需的注解时执行您需要的修改,并使用注入(inject)的字节码生成一个新的类文件。

在这种情况下,您的链条将是:
source -compile -> bytecode -post-compile-> modified bytecode - regular class loader -> loads class into memory
运行时修改

最后我们到达运行时字节码修改。尽管您的想法是可能的,但在我看来,我会保留类加载器的魔力并使用 Javassist 等工具,它也允许您拥有 dynamic proxies可以修改和reloaded .

在 javassist 特定情况下,链将是
source -compile -> bytecode -post-compile-> modified bytecode - regular class loader -> loaded into memory - javassist proxy -> modified class - javassist hot swapper -> re-modified class
代理并不完美(当然没有什么是完美的)。您将受到性能影响,并且您将无法修改类的公共(public)接口(interface)(旁注:APT 和后编译过程都可以允许您修改类公共(public)接口(interface))。我可以在这方面再多说一点,但我认为这已经足够让你深思了。如果您需要更多信息,请随时发表评论。

关于annotations - 字节码注入(inject)发生在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15268057/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com