7

注釈プロセッサを作成するのはこれが初めてであり、プログラムで呼び出したいと思います。出来ますか?

私はプロセッサ用の小さなコードを書きました:

@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)

どんな情報も私にとって非常に役に立ちます。

ありがとう。

4

3 に答える 3

4

次のように、同じプロセス内で、プログラムでアノテーションプロセッサを使用して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上のファイルに基づいてアノテーションプロセッサが自動的に検出されます。META-INF/services/javax.annotation.processing.Processor

于 2014-11-21T13:30:01.137 に答える
4

jOORには、この回答に示されているように、へのアクセスjavax.tools.JavaCompilerを簡素化するAPIがあります。次のように簡単にトリガーできます。

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の背後にある会社で働いています。

于 2018-12-07T14:43:00.790 に答える
3

これは、同様の質問に対する私の回答へのリンクです。

質問で提案した方法で注釈処理を行うこともできますが、どういうわけかとを生成する必要がannotationsありroundEnvます。

注釈処理の使用目的は、コンパイル中です。2段階のコンパイルプロセスをお勧めします。

  1. 通常の方法で注釈プロセッサと関連ファイルをコンパイルします。
  2. 他のファイルをコンパイルします(注釈処理をサポートするコンパイラを使用して)。コンパイラには、プロセッサパス、プロセッサのクラス名など、いくつかの引数が必要になる場合があります。

コンパイラは、annotationsおよびroundEnv変数とプロセッサのインスタンスを生成します。(ほとんどのコンパイラでは、プロセッサがパブリックであり、パブリックコンストラクタが必要です。)次に、コンパイラはprocessメソッドを呼び出します。

于 2012-05-12T17:45:57.823 に答える