Java 注解处理器:自定义注解生成代码
·
Java 注解处理器:自定义注解生成代码指南
1. 核心概念
- 注解处理器:Java 编译器插件,在编译阶段扫描和处理注解
- 工作流程:
graph LR A[源代码] --> B[编译器调用APT] B --> C[注解处理器扫描] C --> D[生成新代码] D --> E[编译新代码]
2. 实现步骤
2.1 定义自定义注解
import java.lang.annotation.*;
@Retention(RetentionPolicy.SOURCE) // 仅保留在源码阶段
@Target(ElementType.TYPE) // 作用于类/接口
public @interface Builder {
String prefix() default "build"; // 带默认值的元素
}
2.2 创建注解处理器
import javax.annotation.processing.*;
import javax.lang.model.element.TypeElement;
import java.util.Set;
@SupportedAnnotationTypes("com.example.Builder") // 处理的注解
@SupportedSourceVersion(SourceVersion.RELEASE_11)
public class BuilderProcessor extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
// 注解处理逻辑
return true; // 表示注解已处理
}
}
2.3 注册处理器(META-INF/services)
创建文件:resources/META-INF/services/javax.annotation.processing.Processor 内容:
com.example.BuilderProcessor
3. 代码生成实战(使用JavaPoet)
// 在process方法内添加:
@Override
public boolean process(Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (Element element : roundEnv.getElementsAnnotatedWith(Builder.class)) {
Builder builder = element.getAnnotation(Builder.class);
String className = element.getSimpleName() + "Builder";
// 使用JavaPoet生成构建器类
TypeSpec builderClass = TypeSpec.classBuilder(className)
.addModifiers(Modifier.PUBLIC, Modifier.FINAL)
.addMethod(generateBuildMethod(element))
.build();
// 写入源文件
JavaFile.builder(getPackage(element), builderClass)
.build()
.writeTo(processingEnv.getFiler());
}
return true;
}
4. 编译配置(Maven)
<dependencies>
<dependency>
<groupId>com.squareup</groupId>
<artifactId>javapoet</artifactId>
<version>1.13.0</version>
</dependency>
<dependency>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
<version>1.0-rc7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>com.google.auto.service</groupId>
<artifactId>auto-service</artifactId>
<version>1.0-rc7</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
5. 使用示例
@Builder(prefix = "create")
public class User {
private String name;
private int age;
}
// 编译后自动生成:
public final class UserBuilder {
public User create() {
return new User(); // 实际生成带参数的构建方法
}
}
6. 调试技巧
- 启用编译日志:
mvn clean compile -X - 处理循环: $$ \text{轮次} = \begin{cases} \text{初始轮} & \text{处理原始注解} \ \text{后续轮} & \text{处理生成的代码} \end{cases} $$
- 错误处理:使用
processingEnv.getMessager()输出错误信息
最佳实践:优先使用注解处理框架(如Google Auto),避免手动文件注册。生成代码时注意避免符号冲突,建议使用
$作为生成类分隔符(如User$Builder)
更多推荐


所有评论(0)