关于Java AbstractProcessor的一些问题?

时间:2017-08-06 04:14:57

标签: java annotations annotation-processing

@SupportedAnnotationTypes({"com.tg.annotation.Table", "com.tg.annotation.Test"})
public class TgDaoGenerateProcessor extends AbstractProcessor {
    private Messager messager;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        messager = processingEnv.getMessager();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        messager.printMessage(Diagnostic.Kind.NOTE, "annotations size " + annotations.size());
}

在我的项目中有一个带注释的类@Table和一个带注释的类@Test

我清理输出目录并在Intellij中构建,输出两行:

annotations size 2
annotations size 0

为什么有两条线? javac做了什么?

如果我重建它,就不会打印任何内容。我想我不会修改源代码,因此javac不会生成新的.class。如果我修改了使用@Table注释并重建的类,则输出为:annotations size 1。 APT获取@Table信息,无法获得@Test注释的课程信息,因为我不会修改注释@Test的课程?

我希望获取带有注释@Table@Test的类信息,并使用它们生成xml文件。举个例子:A类注释@Table和B类注释@Test,APT将获得A类和B类的字段和方法,然后将它们写入新文件。因此,如果仅修改类A,更改某些字段和方法。构建和APT处理器无法获得注释@Test的类B,缺少那些我无法生成最新xml文件的信息。当然,我清理输出目录并重建,它会工作,但没有人愿意这样做。所以改变任何一个类,如何使APT处理器可以获得所有类信息。

1 个答案:

答案 0 :(得分:1)

当你一次提出多个问题时很难回答(这样做是against StackOverflow policies)...让我们先解决不太相关的问题:

  

为什么有牵引线? javac做了什么?

这是因为多轮处理。需要多轮来处理由注释处理器生成的类上的注释。有关详细信息,请参阅documentation of Processor

  

我没有重建任何输出

不要依赖于此。您还没有指定构建系统(IntelliJ Ant?Maven?Gradle?)不同的构建系统以不同的方式处理增量编译,其中一些可能在项目使用注释处理器时完全禁用增量构建。最值得注意的是,Android Gradle插件和最近版本的Gradle本身have disabled增量编译解决了它与注释处理器的兼容性差。

如果您需要简单的方法,请让注释处理器的用户禁用增量编译。或者,您可以重新设计处理器以与增量编译兼容。这是一项复杂的任务,如果您对此感兴趣,我建议您再提一个问题。

  

我修改了一个带注释的类@Table并重建,输出注释大小为1

不要使用process的第一个参数作为任何指示。如果您需要获取带注释的元素,请为您感兴趣的每个注释调用getElementsAnnotatedWith

  

我想获取@Table和@Test注释的类信息,使用它们生成xml文件

您还没有描述处理器的确切目标以及@Table@Test注释的目的,但是如果其中一个类引用另一个(例如@Table - 带注释的类包含@Test - 其中的带注释类型的方法签名),您可以使用getTypeElement访问该类,即使getElementsAnnotatedWith未返回该类。