AbstractProcessor是什么,能做什么,AbstractProcessor如何debug,lombok是如何实现自动生成get/set方法的
AbstractProcessor是什么?
AbstractProcessor是java自身提供的一个编译期触发的处理器接口,需要自己继承并重写其中的方法。 这个处理器可以使用jvm参数来禁用,javac编译一个类时,如果该类上有目标注解,就会触发你的处理器
AbstractProcessor能做什么?
lombok大多数都用过吧,它的内部就是通过AbstractProcessor这个接口在进行编译时动态地生成get/set方法
IDEA配置Remote JVM debug,配置如图,完成后复制图片中选中的jvm参数文本

Preview
IDEA设置中将上一步复制的jvm参数文本复制到图中蓝色选中的地方

Preview
然后就可以在你自定义的Processor中打断点,在需要build或compile的项目中使用Ctrl+shift+F9触发ReBuild,然后就会自动触发第一步配置的remote debug。和正常的debug都是一样的
一个简单的demo
复制
import com.google.auto.service.AutoService;
import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.lang.model.util.Elements;
import javax.lang.model.util.Types;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.Writer;
import java.util.Set;
//这里的 com.demo.TestAnnotation 是一个自定义注解,填写全类名就行,可以多个
@SupportedAnnotationTypes("com.demo.TestAnnotation")
//这里的 AutoService 是 google 的 auto-service 依赖包,可以自动生成 javax.annotation.processing.Processor 配置文件注册你的处理器,就是SPI
@AutoService(TestProcessor.class)
public class TestProcessor extends AbstractProcessor {
Filer filer;
Elements elementUtils;
Types typeUtils;
Messager messager;
@Override
public synchronized void init(ProcessingEnvironment processingEnv) {
super.init(processingEnv);
this.filer = processingEnv.getFiler();
this.elementUtils = processingEnv.getElementUtils();
this.typeUtils = processingEnv.getTypeUtils();
this.messager = processingEnv.getMessager();
}
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
// 运行时依靠 Class 描述一个类,在这里使用 Element 去描述的,有点像 AST(抽象语法树) 了
Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(TestAnnotation.class);
for (Element element : elements) {
String className = element.getSimpleName().toString();
try {
// 这里不指定位置则是默认的输出位置
JavaFileObject classFile = filer.createClassFile(className);
try (Writer writer = classFile.openWriter()) {
writer.write("你生成的类文档代码,可以借助一些工具,比如javapoet");
} catch (IOException e) {
messager.printMessage(Diagnostic.Kind.ERROR, "写入失败");
}
} catch (IOException e) {
messager.printMessage(Diagnostic.Kind.ERROR, e.toString());
}
}
return true;
}
// 支持的 java 版本,也可以使用 @SupportedSourceVersion 指定
@Override
public SourceVersion getSupportedSourceVersion() {
if (SourceVersion.latest().compareTo(SourceVersion.RELEASE_8) > 0) {
return SourceVersion.latest();
}
return SourceVersion.RELEASE_8;
}
}
1
0
92
No data