当前位置: 首页 > news >正文

可信赖的武进网站建设万网 成品网站

可信赖的武进网站建设,万网 成品网站,北京东道设计公司官网,wordpress 牧风主题文章目录一、认识APT1、简介2、工作流程3、回顾注解4、Element常用元素5、Element元素常用变量二、使用注解处理器1、项目一:定义注解2、项目一:实现注解处理器(Processor)3、项目一:注册处理器4、项目一:打…

文章目录

  • 一、认识APT
    • 1、简介
    • 2、工作流程
    • 3、回顾注解
    • 4、Element常用元素
    • 5、Element元素常用变量
  • 二、使用注解处理器
    • 1、项目一:定义注解
    • 2、项目一:实现注解处理器(Processor)
    • 3、项目一:注册处理器
    • 4、项目一:打包
    • 5、项目二:编译期执行
  • 参考资料

一、认识APT

1、简介

APT(Annotation Processing Tool)即注解处理器,它是一种处理注解的工具,也是javac中的一个工具,用于在编译阶段未生成class之前对源码中的注解进行扫描和处理。

APT可以用来在编译时扫描和处理注解, 它可以用来获取到注解和被注解对象的相关信息,在拿到这些信息后我们可以根据需求来自动的生成一些代码,省去了手动编写。APT获取注解及生成代码都是在代码编译时候完成的,相比反射在运行时处理注解大大提高了程序性能。

2、工作流程

在这里插入图片描述

3、回顾注解

因为APT = 注解+ 注解处理器(AbstractProcessor)。这里就不详细介绍Java注解了。
特别关注一下下元注解@Retention

@Retention这个注解是用来修饰注解定义的,作用是被修饰的注解可以保存多久,这个注解需要使用参数。
这个参数的类型是RetentionPolicy,所以使用这个注解就要对value赋值。
value的值有且仅有三个:
->RetenionPolicy.CLASS编译器把该注解记录在class文件中。当运行java程序时,JVM不可获取注解信息。这是默认值!
->RetenionPolicy.RUNTIME编译器把该注解记录在class文件中。当运行java程序时,JVM可获取注解信息,程序可以通过反射获取该注解信息
->RetenionPolicy.SOURCE该注解只保存在源代码中,编译器直接丢弃该注解。

因为APT是在java编译器使用,因此@Retention的value通常指定为source或者class,这样可以提高一点性能。就我个人而言,我倾向指定为source

关于注解:https://blog.csdn.net/A_art_xiang/article/details/107985113

4、Element常用元素

element是代表程序的一个元素,这个元素可以是:包、类/接口、属性变量、方法/方法形参、泛型参数。element是java-apt(编译时注解处理器)技术的基础,因此如果要编写此类框架,熟悉element是必须的。
在这里插入图片描述

5、Element元素常用变量

在这里插入图片描述

二、使用注解处理器

1、项目一:定义注解

开发者先定义需要处理的注解(如 @Data、@Inject 等),并指定注解的保留策略为 SOURCE 或 CLASS(APT 只能处理编译期可见的注解,RUNTIME 注解在编译期已被丢弃)。

// 示例:定义一个用于生成Builder模式的注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.TYPE)  // 作用于类/接口
@Retention(RetentionPolicy.SOURCE)  // 仅在源码中保留
public @interface GenerateBuilder {
}

2、项目一:实现注解处理器(Processor)

通过继承 javax.annotation.processing.AbstractProcessor 类,重写关键方法来定义注解的处理逻辑。核心方法包括:
init(ProcessingEnvironment env):初始化处理器,获取工具类(如用于生成代码的 Filer、用于输出日志的 Messager 等)。
getSupportedAnnotationTypes():指定当前处理器支持处理的注解类型(全类名)。
process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv):处理注解的核心逻辑,通过 roundEnv 获取被注解的元素(类、方法等),并生成新代码。

import javax.annotation.processing.*;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.io.IOException;
import java.io.Writer;
import java.util.Set;// 声明支持的注解和Java版本、支持的注解
@SupportedAnnotationTypes("com.demo.springbootdemo.test.GenerateBuilder")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class BuilderProcessor extends AbstractProcessor {private Messager messager; // 用于输出日志/错误信息private Filer filer;       // 用于生成Java文件@Overridepublic synchronized void init(ProcessingEnvironment processingEnv) {super.init(processingEnv);messager = processingEnv.getMessager();filer = processingEnv.getFiler();}@Overridepublic boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {// 遍历所有被@GenerateBuilder注解的元素for (Element element : roundEnv.getElementsAnnotatedWith(GenerateBuilder.class)) {// 只处理类if (element.getKind().isClass()) {TypeElement typeElement = (TypeElement) element;generateBuilderClass(typeElement);} else {// 非类元素使用注解时报错messager.printMessage(Diagnostic.Kind.ERROR, "@GenerateBuilder can only be used on classes", element);}}return true; // 表示注解已被处理}// 生成Builder类private void generateBuilderClass(TypeElement typeElement) {String className = typeElement.getSimpleName().toString();String packageName = processingEnv.getElementUtils().getPackageOf(typeElement).getQualifiedName().toString();String builderClassName = className + "Builder";try {// 创建Java源文件JavaFileObject file = filer.createSourceFile(packageName + "." + builderClassName);try (Writer writer = file.openWriter()) {// 写入Builder类代码writer.write("package " + packageName + ";\n\n");writer.write("public class " + builderClassName + " {\n");writer.write("    private " + className + " target = new " + className + "();\n\n");// 生成setter方法(简化示例,实际需遍历类的字段)writer.write("    public " + builderClassName + " setId(int id) {\n");writer.write("        target.id = id;\n");writer.write("        return this;\n");writer.write("    }\n\n");writer.write("    public " + builderClassName + " setName(String name) {\n");writer.write("        target.name = name;\n");writer.write("        return this;\n");writer.write("    }\n\n");// 生成build方法writer.write("    public " + className + " build() {\n");writer.write("        return target;\n");writer.write("    }\n");writer.write("}\n");}messager.printMessage(Diagnostic.Kind.NOTE, "Generated Builder class: " + builderClassName);} catch (IOException e) {messager.printMessage(Diagnostic.Kind.ERROR, "Failed to generate Builder class: " + e.getMessage());}}
}

3、项目一:注册处理器

APT 需要知道哪些处理器用于处理注解。在 Java 中,使用SPI机制,处理器通过 META-INF/services/javax.annotation.processing.Processor 文件注册,文件内容为处理器的全类名:

org.example.test.BuilderProcessor

4、项目一:打包

将项目一打成jar包,为其他工程服务

5、项目二:编译期执行

当使用 javac 编译代码,或者使用idea进行builder时,APT 会自动扫描注解,调用对应的处理器生成代码。生成的代码会与源文件一起被编译为 class 文件。

import org.example.test.GenerateBuilder;@GenerateBuilder  // 标记需要生成Builder的类
public class User {public int id;public String name;
}

build之后,生成了class文件:
在这里插入图片描述

java代码生成可以考虑借鉴javapoet进行源代码生成

参考资料

https://juejin.cn/post/7220696541307650109

http://www.dtcms.com/a/537639.html

相关文章:

  • 大气物流网站模块电商支付网站建设费进什么科目
  • Unity_Canvas_Canvas Scaler画布缩放器。
  • 邢台建设网站公司做网站买那种服务器
  • 企业智能体:企业智脑的最小智能单元,灵活响应多样化业务需求
  • Qt6中文路径
  • 操作系统5.3.5 固态硬盘SSD
  • 最强的手机网站建设环保行业网站开发
  • 二叉树笔记 2025-10-22
  • Gitee仓库清理指南:如何移除误传的无关文件并正确使用.gitignore
  • Linux下编译mjansson/mdns
  • 沈阳招标信息网网站排名优化建设
  • 建设宣传网站上的请示重庆专业网站公司
  • MySQL 深度解析:varchar (50) 与 varchar (500) 的底层差异及选型实践
  • 蓝桥杯知识点大纲(JavaC组)
  • 济南建站网站泛华建设集团有限公司网站
  • 如何做后台网站增删改企业二级域名自助建站平台
  • 网站建设在哪里发布网站页面建设方案书模板
  • 青岛seo网站关键词优化黑龙江建设人员证件查询网站
  • ansible实战- 关机
  • 做网站域名需哪些自贡企业网站建设公司
  • 网站建设与维护方案找建设企业网站公司
  • 网站备案名称修改seo关键词排名优化怎样收费
  • 外销网站php培训
  • 做wow宏的网站网站服务器租用一般费用
  • Rust宏编程完全指南:从基础到高级的元编程艺术
  • 网站制作 徐州哪个网站开发培训好
  • 做网站需要哪些钱做视频网站需要什么服务器
  • 前端3D开发面试全攻略WebGLThreeJS方向
  • 班级网站建设模板下载佛山建设网站
  • 【Linux】进程概念(四)(命令行参数和环境变量)