簡體   English   中英

以編程方式調用注釋處理器

[英]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)

任何信息對我都非常有幫助。

謝謝。

這是我對類似問題的回答的鏈接。

您可以按照您在問題中建議的方式進行注釋處理,但是您必須以某種方式生成annotationsroundEnv

注釋處理的預期用途是在編譯期間。 我建議兩步編譯過程。

  1. 以通常的方式編譯注釋處理器和相關文件。
  2. 編譯其他文件(使用支持注釋處理的編譯器)。 您可能需要編譯器的一些參數:處理器路徑,處理器的類名等。

編譯器將生成annotationsroundEnv變量以及處理器的實例。 (大多數編譯器要求您的處理器是公共的,具有公共構造函數。)然后,編譯器將調用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM