概念
注解处理器(Annotation Processor)是javac内置的一个用于编译时扫描和处理注解(Annotation)的工具。简单的说,在源代码编译阶段,通过注解处理器,我们可以获取源文件内注解(Annotation)相关内容javax.annotation.processing.Processor
用于替换JDK6之前的APT(Annotatino Processing Tool)
用途
由于注解处理器可以在程序编译阶段工作,所以我们可以在编译期间通过注解处理器进行我们需要的操作。比较常用的用法就是在编译期间获取相关注解数据,然后动态生成.java源文件(让机器帮我们写代码),通常是自动产生一些有规律性的重复代码,解决了手工编写重复代码的问题,大大提升编码效率。
技术
javax.annotation.processing.Processor
public interface Processor {
//返回此 processor 识别的选项。处理工具的实现必须提供一种方式来传递特定于 processor 的选项,这些选项不同于传递给工具自身的选项,
Set<String> getSupportedOptions();
//返回此 processor 支持的注释类型的名称。结果元素可能是某一受支持注释类型的规范(完全限定)名称。它也可能是 "name.*" 形式的名称,表示所有以 "name." 开头的规范名称的注释类型集合。最后,"*" 自身表示所有注释类型的集合,包括空集。注意,processor 不应声明 "*",除非它实际处理了所有文件;声明不必要的注释可能导致在某些环境中的性能下降。
Set<String> getSupportedAnnotationTypes();
//用于指定你的java版本,一般返回:SourceVersion.latestSupported()
SourceVersion getSupportedSourceVersion();
//用处理环境初始化处理器。
void init(ProcessingEnvironment processingEnv);
//处理先前 round 产生的类型元素上的注释类型集,并返回这些注释是否由此 processor 声明。如果返回 true,则这些注释已声明并且不要求后续 processor 处理它们;如果返回 false,则这些注释未声明并且可能要求后续 processor 处理它们。processor 可能总是返回相同的 boolean 值,或者可能基于所选择的标准而返回不同的结果。
如果 processor 支持 "*" 并且根元素没有注释,则输入集合将为空。processor 必须妥善处理空注释集。
boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv);
quot;),
Iterable<? extends Completion> getCompletions(Element element,
AnnotationMirror annotation,
ExecutableElement member,
String userText);
}
javax.annotation.processing.AbstractProcessor
对其父类的获取配置信息的扩充,使其获取支持的版本号,扫描的注解信息等可以使用注解方式等,推荐使用
javax.annotation.processing.SupportedSourceVersion 直接支持的版本
javax.annotation.processing.SupportedOptions 支持的选项参数名称。通过getOptions方法获取选项参数值
javax.annotation.processing.SupportedAnnotationTypes 支持的注解
public Set<String> getSupportedOptions() {
SupportedOptions so = this.getClass().getAnnotation(SupportedOptions.class);
if (so == null)
return Collections.emptySet();
else
return arrayToSet(so.value());
}
public Set<String> getSupportedAnnotationTypes() {
SupportedAnnotationTypes sat = this.getClass().getAnnotation(SupportedAnnotationTypes.class);
if (sat == null) {
if (isInitialized())
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
"No SupportedAnnotationTypes annotation " +
"found on " + this.getClass().getName() +
", returning an empty set.");
return Collections.emptySet();
}
else
return arrayToSet(sat.value());
}
public SourceVersion getSupportedSourceVersion() {
SupportedSourceVersion ssv = this.getClass().getAnnotation(SupportedSourceVersion.class);
SourceVersion sv = null;
if (ssv == null) {
sv = SourceVersion.RELEASE_6;
if (isInitialized())
processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING,
"No SupportedSourceVersion annotation " +
"found on " + this.getClass().getName() +
", returning " + sv + ".");
} else
sv = ssv.value();
return sv;
}
Demo
- @SupportedAnnotationTypes(“org.mapstruct.Mapper”) 只支持org.mapstruct.Mapper注解
- @SupportedAnnotationTypes(“javax.xml.bind.annotation.*”) 支持javax.xml.bind.annotation 包下所有注解
- @SupportedAnnotationTypes("*") 支持所有注解