我有我的注释处理器:
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'
}
答案 0 :(得分:0)
坏消息:注释处理器无法做到这一点-其回合工作方式的本质意味着,在“实际”源所在的同一目录中生成源就没有意义了,因为这些生成的源下次运行注释处理器时,它将被视为输入。
好消息: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()
不需要任何现有的源代码来自同一项目来运行,这应该很简单。
答案 1 :(得分:0)
不确定gradle,但是通过maven,您可以使用maven-compiler-plugin中的以下标签定义生成的源目录。
<generatedSourcesDirectory>
${project.basedir}/src/main/java
</generatedSourcesDirectory>
有关完整示例,请检查以下链接。
https://www.thetechnojournals.com/2019/12/annotation-processor-to-generate-dto.html