关于Processor接口的process(...)方法中定义的参数

Posted

技术标签:

【中文标题】关于Processor接口的process(...)方法中定义的参数【英文标题】:About the parameter defined in process(...) method of Processor interface 【发布时间】:2020-01-24 16:52:45 【问题描述】:

javax.annotation.processing包中有一个接口Processor,其中有一个函数:

/**
     * Processes a set of annotation types on type elements
     * originating from the prior round and returns whether or not
     * these annotation types are claimed by this processor.  If @code
     * true is returned, the annotation types are claimed and subsequent
     * processors will not be asked to process them; if @code false
     * is returned, the annotation types are unclaimed and subsequent
     * processors may be asked to process them.  A processor may
     * always return the same boolean value or may vary the result
     * based on chosen criteria.
     *
     * <p>The input set will be empty if the processor supports @code
     * "*" and the root elements have no annotations.  A @code
     * Processor must gracefully handle an empty set of annotations.
     *
     * @param annotations the annotation types requested to be processed
     * @param roundEnv  environment for information about the current and prior round
     * @return whether or not the set of annotation types are claimed by this processor
     */
    boolean process(Set<? extends TypeElement> annotations,
                    RoundEnvironment roundEnv);

Java API AbstractProcessor 实现了上述接口。现在我创建了自己的处理器类:

public class MyProcessor extends AbstractProcessor 
   ...
   @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) 

        for (TypeElement annotation: annotations) 
            // How can I get the class of the annotation ?
        
    

我的问题:

    API 文档告诉我进程函数中的annotations

请求处理的注解类型

那么,为什么它的类型是 TypeElement 而不是 java.lang.annotation.Annotation ?我对此感到困惑,因为我不确定annotations 究竟是指被注释的元素还是真正的注释元素。

    由于我上面的第一个问题,如何从TypeElement 获取每个注释的类?

【问题讨论】:

【参考方案1】:

有一个包javax.lang.model 遵循Mirrors: Design Principles for Meta-level Facilities of Object-Oriented Programming Languages 中描述的基于镜像的设计。它是用于(但不限于)注释处理框架中的一个经过精心设计的抽象。

    那么,为什么是TypeElement而不是java.lang.annotation.Annotation

    当您设计一个框架时,重要的是保留它open(可用于扩展)。你永远不知道该语言的未来版本会带来什么。假设可能出现新形式的元数据,您需要保持灵活性。

    我对此感到困惑,因为我不确定注释实际上是指被注释的元素还是真正的注释注释元素。

    这是“真正的注释元素”,因为您正在处理注释类型。

    for (TypeElement typeElement : annotations) 
        // it's likely the ElementKind.ANNOTATION_TYPE
        typeElement.getKind();
    
        // elements annotated with the annotation
        environment.getElementsAnnotatedWith(typeElement);
    
    

    由于我上面的第一个问题,如何从TypeElement 获取每个注释的类?

    TypeElement代表你的注解类。

阅读:

    https://bracha.org/mirrors.pdf(处理时间较长)

    https://www.baeldung.com/java-annotation-processing-builder(它是一个简单的注释处理器)

    https://github.com/rzwitserloot/lombok/blob/master/src/core/lombok/core/AnnotationProcessor.java(这是一个很好的practical 示例)

    the package的Javadoc和ProcessorAnnotatedConstructElementTypeElementTypeMirror等核心类。

【讨论】:

感谢您的回答。我想你误解了我的第二个问题。我知道TypeElement 代表注释类,但它不是注释类。我的意思是如何获得我的注释的 Class 实例。比如我有一个自定义注解@MyAnnotation,我想从TypeElement得到MyAnnotation.class,可以吗? 关于您对我的第一个问题的回答。我也知道开闭原理,但是Annotation是一个接口,它不是任何东西的具体实现。我仍然在寻找一个令人信服的理由,为什么 Set&lt;? extends TypeElement&gt; annotations 在其设计中不是 Set&lt;? extends Annotation&gt; 类型并且变量名称是 annotations。此外,您错过了我的问题,我想知道该集合是代表我的所有自定义注释还是由我的注释注释的所有元素。 @Leem.fin java.lang.Annotation 不是javax.lang.model 抽象的一部分(这就是为什么它是Set&lt;? extends TypeElement&gt;),我猜annotations 在a broader sense 中使用(它没有不一定是指我们知道的Annotation 接口)。请注意,可以轻松更改 Javadoc,而不会影响源代码。 @Leem.fin 我包含了它(“真正的注释注释元素”):这是你的注释。要获取使用注释注释的元素,您需要一个环境,并且您执行 environment.getElementsAnnotatedWith(参见上面的 sn-p) “代表我所有的自定义注释” 有点不准确。 “表示我支持(或我的注释处理器支持)的所有注释”更精确(参见@SupportedAnnotationTypes

以上是关于关于Processor接口的process(...)方法中定义的参数的主要内容,如果未能解决你的问题,请参考以下文章

Java Annotation Processor:检查TypeMirror是否实现特定的通用接口

Tomcat请求处理流程与源码浅析

Jmeter 接口测试对上接口结果二次处理作为入参 Bean Shell Processor

七十一:flask钩子函数之关于context_processor的钩子函数

加速PowerShell Get-Counter和Get-Process

多次捕获异常 - C#