[英]Programmatically invoke Annotation Processors
这是我第一次编写Annotation Processor,我想以编程方式调用它。 可能吗?
我为处理器编写了小代码:
@SupportedAnnotationTypes({"app.dev.ems.support.annotation.HBMModel"})
public class HBMModelProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(HBMModel.class);
System.out.println(elements);
return true;
}
}
现在如果我想调用流程方法,那我该怎么做呢? 我可以通过以下方式完成:
HBMModelProcessor modelProcessor = new HBMModelProcessor();
modelProcessor.process(annotations, roundEnv)
任何信息对我都非常有帮助。
谢谢。
这是我对类似问题的回答的链接。
您可以按照您在问题中建议的方式进行注释处理,但是您必须以某种方式生成annotations
和roundEnv
。
注释处理的预期用途是在编译期间。 我建议两步编译过程。
编译器将生成annotations
和roundEnv
变量以及处理器的实例。 (大多数编译器要求您的处理器是公共的,具有公共构造函数。)然后,编译器将调用process
方法。
您可以在同一进程中以编程方式使用注释处理器调用Java编译器,如下所示:
import com.sun.tools.javac.processing.PrintingProcessor;
import fi.jumi.actors.generator.JavaSourceFromString;
import org.junit.*;
import org.junit.rules.TemporaryFolder;
import javax.annotation.processing.Processor;
import javax.tools.*;
import javax.tools.JavaCompiler.CompilationTask;
import java.io.IOException;
import java.util.Arrays;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
public class ExampleTest {
@Rule
public final TemporaryFolder tempDir = new TemporaryFolder();
@Test
public void example() throws IOException {
JavaFileObject src = new JavaSourceFromString(
"com.example.GuineaPig",
"package com.example;\n" +
"public interface GuineaPig {\n" +
" void foo();\n" +
"}"
);
compile(new PrintingProcessor(), src);
}
private void compile(Processor processor, JavaFileObject... compilationUnits) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(tempDir.getRoot()));
CompilationTask task = compiler.getTask(null, fileManager, diagnostics, null, null, Arrays.asList(compilationUnits));
task.setProcessors(Arrays.asList(
processor
));
boolean success = task.call();
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
System.err.println(diagnostic);
}
assertThat("compile succeeded", success, is(true));
}
}
如果删除对setProcessors
的调用, setProcessors
根据类路径上的META-INF/services/javax.annotation.processing.Processor
文件自动检测注释处理器。
jOOR有一个API来简化对javax.tools.JavaCompiler
访问,如本答案所示 。 您可以按如下方式轻松触发:
Reflect.compile(
"com.example.MyClass",
"package com.example; "
+ "@app.dev.ems.support.annotation.HBMModel "
+ "class MyClass {}",
new CompileOptions().processors(new HBMModelProcessor())
);
这对于单元测试注释处理器特别有用。 另请参阅此博客文章: https : //blog.jooq.org/2018/12/07/how-to-unit-test-your-annotation-processor-using-joor
免责声明,我为jOOR背后的公司工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.