2

我有我的注释处理器:

public class MyAnnotationProcessor extends AbstractProcessor {
    ...

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        // Here I deal with the annotated element
         ...

        // use JavaPoet to generate Java source file
        TypeSpec generatedClazz = generate_code();
        JavaFile javaFile = JavaFile.builder("com.my.foo", generatedClazz).build();
        javaFile.writeTo(filer);
    }

}

在上述process回调中处理注释元素后,我使用JavaPoet生成 java 源代码并为代码创建 Java 文件。构建我的项目时,除了生成的 java 源代码文件默认转到build/generated/sources/myApp/com/my/foo. 如何使生成的 Java 文件位于项目的源代码位置src/main/java/com/my/foo

我的 gradle 构建:

plugins {
    id 'java'
}

group 'com.my.app'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {

    testImplementation 'junit:junit:4.12'

    implementation 'com.squareup:javapoet:1.11.1'
    implementation 'com.google.guava:guava:28.1-jre'
}
4

2 回答 2

1

不确定 gradle,但使用 maven,您可以使用 maven-compiler-plugin 中的以下选项卡定义生成的源目录。

<generatedSourcesDirectory>
     ${project.basedir}/src/main/java
</generatedSourcesDirectory>

有关完整示例,请查看以下链接。

https://www.thetechnojournals.com/2019/12/annotation-processor-to-generate-dto.html

于 2019-12-05T16:45:26.750 回答
1

坏消息:注释处理器无法做到这一点——他们的轮次工作的性质意味着在“实际”源所在的同一目录中生成源是没有意义的,因为这些生成的源将被处理作为下次注释处理器运行时的输入。

好消息:JavaPoet 不知道您实际调用它的方式,因此您可以编写一个简单的 main() 来生成代码,并在构建时要求您的 IDE 调用它,或者将其附加到您的 gradle 构建中。如果您计划在生成源代码后手动编辑它们,您可能不希望发生这种情况,因为您可能希望保留手动更改,而不是在每次构建时都被覆盖。

JavaFile.writeTo(...)方法有几个覆盖,其中只有一个采用注释处理器Filer。使用Filer有一些优点 - 非常清楚您打算在哪里编写类 - 但JavaFile.writeTo(File directory)也意味着以这种方式使用。您不会将您希望 MyClass.java 所在的实际文件传递给它,而只是传递您要写入的源目录。在你的情况下,这大概是javaFile.writeTo(new File("myProject/src/main/java")).

您可能仍然应该参数化如何调用此 main,以便它知道要使用哪些输入,如何理解您现有的源等。另一方面,如果您generate_code()不需要来自同一项目的任何现有源来运行,这应该很简单。

于 2019-10-10T21:11:16.203 回答