【问题标题】:How do you use Java 1.6 Annotation Processing to perform compile time weaving?如何使用 Java 1.6 Annotation Processing 执行编译时编织?
【发布时间】:2011-02-13 05:42:09
【问题描述】:

我创建了一个注解,将它应用到一个 DTO 并编写了一个 Java 1.6 风格的注解处理器。我可以看到如何让 annotationProcessor 编写一个新的源文件,这不是我想要做的,我看不到或知道如何让它修改现有的类(理想情况下只是修改字节码)。修改实际上相当简单,我希望处理器做的只是插入一个新的 getter 和 setter,其中名称来自正在处理的注释的值。

我的注释处理器看起来像这样;

@SupportedSourceVersion(SourceVersion.RELEASE_6)
@SupportedAnnotationTypes({ "com.kn.salog.annotation.AggregateField" })
public class SalogDTOAnnotationProcessor extends AbstractProcessor {

    @Override
    public boolean process(final Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
        //do some stuff
    }
}

【问题讨论】:

    标签: java annotations compile-time-weaving annotation-processing


    【解决方案1】:

    您正在寻找“仪器”,这就是 AspectJ 之类的框架所做的。在这种情况下,您必须在命令行中使用“-agent”选项指定一个 jar,然后才能过滤所有加载的类。在此过滤步骤中,您可以检查注释,并在字节码加载到虚拟机之前对其进行修改。进行实际字节码修改的库包括“asm”,也许还有高级包装器“cglib”和“javassist”。您甚至可以预编译您的类以生成必须由您检测的类列表,以便在开始时更快地进行过滤。

    有关更多信息,请参阅 java.lang.instrumentation。

    【讨论】:

      【解决方案2】:

      根据设计,注释处理工具不允许直接修改正在处理的源代码。但是,可以生成正在处理的类型的子类或正在处理的类型的超类。通过一些计划,这确实允许修改相关类型的一些效果。我已经写了一个如何组合在一起的例子;更详细的解释和一些示例代码见this blog entry

      【讨论】:

        【解决方案3】:

        你必须使用内部编译器的类——一些灵感:

        但这是边缘政策。您的程序只能在 Sun/OpenJDK 上编译,并且在未来的版本中可能会出现问题(内部 API 可能会更改)。虽然一旦编译,它是标准字节码,并且会在任何地方运行。

        顺便说一句:如果你想在 Eclipse 中使用它,你应该为它添加一些特殊的支持,因为 Eclipse 使用非标准编译器。你的设计应该更复杂,你应该为你的处理器添加一个抽象级别——就像Lombok一样。

        【讨论】:

        • 这些都是很棒的例子。谢谢!
        【解决方案4】:

        您必须为此扩展javac 编译器,这意味着构建您的程序不会像常规应用程序那样可移植。请参阅http://weblogs.java.net/blog/cayhorstmann/archive/2006/06/say_no_to_prope.html,了解有关某人如何实现这一目标的更多详细信息。

        【讨论】:

        • 这当然是一个解决方案,但我很确定这不是唯一的解决方案。我想做的事情可以通过几个现有的框架/工具集来完成,例如 javassist。我试图避免引入似乎并非绝对必要的依赖项,但在 JDK1.6 中引入注解处理看起来像是 javassist 的功能正在被加入。也许我错了,我仍然需要第三个执行编译时编织的派对工具。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-27
        • 2012-12-28
        • 1970-01-01
        相关资源
        最近更新 更多