java注解处理器基于jsr 269在编译期生成代码:先定义source保留级别的自定义注解,再继承abstractprocessor实现process()方法,通过filer生成.java文件,最后通过meta-inf/services或构建工具注册处理器,生成代码自动参与后续编译。

Java 在编译期通过注解处理器(Annotation Processor)生成代码,核心是利用 JSR 269 注解处理框架,在 javac 编译过程中扫描特定注解,并调用你写的处理器生成 .java 源文件(或 .class 文件),这些新生成的代码会自动参与后续编译流程。
1. 定义自定义注解
注解必须声明为 @Retention(RetentionPolicy.SOURCE)(仅保留在源码期)或 CLASS(但处理器通常只关心 SOURCE),并加上 @Target 明确作用位置:
- 不要用 RUNTIME——运行时注解无法被注解处理器捕获;
- 推荐加
@Documented和@Repeatable(如需)提升可用性; - 示例:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface GenerateBuilder {
}
2. 编写注解处理器(Processor)
继承 AbstractProcessor,重写 process() 方法。关键点:
- 在
getSupportedAnnotationTypes()中声明支持哪些注解(推荐用字符串,避免类加载问题); - 用
RoundEnvironment获取被注解的元素(Element),例如getTypeElementsAnnotatedWith(); - 用
Filer创建新 Java 源文件(filer.createSourceFile()),配合JavaFileObject.openWriter()写入内容; - 用
Messager输出提示或错误(messager.printMessage(Diagnostic.Kind.NOTE, "..."));
3. 注册处理器并参与编译
有两种主流方式让编译器发现你的处理器:
-
META-INF/services/javax.annotation.processing.Processor:在资源目录下创建该文件,每行写一个处理器全限定名(如
com.example.MyProcessor); -
使用 Gradle/Maven 插件显式声明(更可靠,尤其多模块项目):
Gradle 示例:compileOnly 'com.example:processor:1.0'<br> annotationProcessor 'com.example:processor:1.0' - 注意:处理器 JAR 必须包含
Processor类且不能依赖未在编译期可见的运行时库(如 Spring);
4. 生成代码的注意事项
生成的代码不是“黑盒”,它和手写代码一样参与完整编译流程:
- 生成的
.java文件会被 javac 自动编译成.class; - 可被其他注解处理器再次处理(需注意处理顺序,用
@SupportedOptions或getSupportedSourceVersion()协调); - 避免生成语法错误代码——否则编译直接失败;建议用 JavaPoet 等库安全构造代码结构;
- 不要尝试在
process()中修改已有源码(JSR 269 不允许),只能生成新文件;
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











