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

深入浅出 Java 注解处理器:从原理到实战,一键生成代码

在日常 Java 开发中你一定用过Override、Autowired、Data这些注解它们极大简化了代码开发。但你有没有想过Lombok 是如何通过一个 Data 就自动生成 get/set 方法MyBatis-Plus 的代码生成器、Spring 的依赖注入底层都依赖什么技术实现答案就是Java 注解处理器Annotation Processor。它是 JDK 1.6 提供的编译期特性能在编译阶段扫描、处理注解自动生成代码、校验语法、修改字节码。本文将带你从零吃透注解处理器从核心原理到实战开发手把手实现一个自定义注解 注解处理器看完就能自己写代码生成工具一、注解处理器核心概念1. 什么是注解处理器插入广告各行各业学习千款源码就上svipm.com.cn注解处理器是运行在编译期的工具不属于运行时逻辑。它的工作流程编译器编译 Java 文件时扫描所有类上的注解匹配到自定义注解处理器后执行处理逻辑生成新的 Java 文件 / 字节码、打印日志、抛出编译异常等编译器继续编译生成的文件最终打包到 class 文件中。关键特性编译期执行不影响运行时性能无需反射无性能损耗可自动生成代码减少重复开发常用于框架底层Lombok、Spring、ButterKnife。2. 核心 API 与依赖开发注解处理器核心依赖两个模块自定义注解标记需要处理的类 / 方法 / 字段注解处理器继承AbstractProcessor重写处理逻辑SPI 配置让编译器找到自定义处理器关键。JDK 核心 APIAbstractProcessor所有处理器的父类Element编译期元素类、方法、字段、参数JavaFileObject生成 Java 源码的工具类ProcessingEnvironment编译期环境工具。二、注解处理器工作流程编译期一句话总结编译器启动 → 扫描注解 → 匹配处理器 → 执行处理 → 生成代码 → 完成编译。详细流程源码编译阶段.java→ 抽象语法树AST注解处理阶段处理器扫描 AST 上的注解逻辑处理解析注解参数生成新的 Java 文件循环处理新生成的文件也会被扫描直到无新文件生成最终编译所有源码编译为.class文件。注意注解处理器不能修改已有 Java 源码只能生成新的源码 / 字节码Lombok 看似修改源码本质是通过修改抽象语法树实现的高级操作。三、开发环境准备本文使用Maven构建项目分为两个模块annotation存放自定义注解processor存放注解处理器依赖 annotation 模块。为什么拆分模块因为注解处理器需要在编译期独立运行拆分后避免业务代码与处理器代码耦合。Maven 依赖配置1. annotation 模块纯注解无其他依赖xmldependencies !-- 无需运行时依赖 -- /dependencies2. processor 模块核心依赖xmldependencies !-- 依赖自定义注解模块 -- dependency groupIdcom.example/groupId artifactIdannotation/artifactId version1.0-SNAPSHOT/version /dependency !-- 编译期工具依赖 -- dependency groupIdcom.squareup/groupId artifactIdjavapoet/artifactId version1.13.0/version /dependency /dependencies build plugins !-- 编译JDK版本 -- plugin groupIdorg.apache.maven.plugins/groupId artifactIdmaven-compiler-plugin/artifactId version3.8.1/version configuration source8/source target8/target encodingUTF-8/encoding /configuration /plugin /plugins /buildJavaPoetSquare 开源的代码生成框架简化 Java 源码生成推荐使用。四、实战开发自定义注解处理器我们实现一个自动生成 Builder 构造器的注解处理器自定义AutoBuilder注解标记在实体类上编译期自动生成XXXBuilder类支持链式调用简化对象创建。步骤 1定义自定义注解在annotation模块创建AutoBuilderjava运行import java.lang.annotation.*; /** * 自动生成Builder模式的注解 * 作用目标类 * 生命周期编译期SOURCE运行时无需保留 */ Target(ElementType.TYPE) Retention(RetentionPolicy.SOURCE) public interface AutoBuilder { }Retention(SOURCE)注解只在源码阶段存在编译后丢弃节省资源Target(ElementType.TYPE)只能标记在类上。步骤 2开发注解处理器核心继承AbstractProcessor重写 4 个核心方法init()初始化获取环境工具process()核心处理方法扫描注解、生成代码getSupportedAnnotationTypes()指定支持的注解getSupportedSourceVersion()指定 JDK 版本。在processor模块创建AutoBuilderProcessorjava运行import com.example.annotation.AutoBuilder; import com.squareup.javapoet.*; 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 java.io.IOException; import java.util.Set; /** * 自定义注解处理器 * 处理AutoBuilder注解生成Builder类 */ SupportedSourceVersion(SourceVersion.RELEASE_8) public class AutoBuilderProcessor extends AbstractProcessor { // 元素工具类获取类、字段、方法信息 private Elements elementUtils; /** * 初始化方法 */ Override public synchronized void init(ProcessingEnvironment processingEnv) { super.init(processingEnv); elementUtils processingEnv.getElementUtils(); } /** * 核心处理方法 * param annotations 待处理的注解集合 * param roundEnv 编译环境 * return 是否处理完成 */ Override public boolean process(Set? extends TypeElement annotations, RoundEnvironment roundEnv) { // 1. 扫描所有被AutoBuilder标记的类 Set? extends Element elements roundEnv.getElementsAnnotatedWith(AutoBuilder.class); for (Element element : elements) { // 强转为类元素 TypeElement typeElement (TypeElement) element; // 获取类名 String className typeElement.getSimpleName().toString(); // 获取包名 String packageName elementUtils.getPackageOf(typeElement).getQualifiedName().toString(); // 2. 使用JavaPoet生成Builder类 generateBuilderClass(packageName, className, typeElement); } return true; } /** * 生成Builder模式代码 */ private void generateBuilderClass(String packageName, String className, TypeElement typeElement) { // 生成的类名User → UserBuilder String builderClassName className Builder; // 构建类 TypeSpec.Builder builder TypeSpec.classBuilder(builderClassName) .addModifiers(javax.lang.model.element.Modifier.PUBLIC); // 生成build()方法 MethodSpec buildMethod MethodSpec.methodBuilder(build) .addModifiers(javax.lang.model.element.Modifier.PUBLIC) .returns(ClassName.get(packageName, className)) .addStatement(return new $N(), className) .build(); builder.addMethod(buildMethod); // 生成Java文件 JavaFile javaFile JavaFile.builder(packageName, builder.build()) .build(); // 写入文件到项目中 try { javaFile.writeTo(processingEnv.getFiler()); System.out.println(✅ 生成Builder类成功 packageName . builderClassName); } catch (IOException e) { e.printStackTrace(); } } /** * 指定支持的注解全类名 */ Override public SetString getSupportedAnnotationTypes() { return Set.of(AutoBuilder.class.getCanonicalName()); } }步骤 3SPI 配置让编译器找到处理器这是最关键的一步不配置 SPI编译器无法识别自定义处理器。创建文件路径plaintextprocessor/src/main/resources/META-INF/services/javax.annotation.processing.Processor文件内容处理器全类名plaintextcom.example.processor.AutoBuilderProcessor步骤 4测试使用注解处理器打包annotation和processor模块mvn clean install在业务项目中引入依赖xmldependency groupIdcom.example/groupId artifactIdannotation/artifactId version1.0-SNAPSHOT/version /dependency dependency groupIdcom.example/groupId artifactIdprocessor/artifactId version1.0-SNAPSHOT/version scopeprovided/scope /dependency创建实体类使用AutoBuilderjava运行import com.example.annotation.AutoBuilder; AutoBuilder public class User { private Long id; private String name; }编译项目mvn compile查看生成的代码target/generated-sources/annotations/com/example/UserBuilder.java五、注解处理器常见问题1. 处理器不生效检查 SPI 文件路径、名称、内容是否正确检查getSupportedAnnotationTypes返回的注解全类名清理缓存mvn clean重新编译。2. 编译报错程序包不存在确保注解模块已正确打包依赖引入无误检查模块间依赖关系。3. 可以修改已有源码吗不能直接修改只能生成新的 Java 文件。Lombok 通过修改 AST 实现属于高级黑魔法不推荐新手使用。4. 运行时需要依赖处理器吗不需要处理器是编译期工具打包时scopeprovided/scope即可不会打入运行包。六、注解处理器应用场景代码生成Lombok、MyBatis-Plus 代码生成器、Builder / 工厂模式自动生成编译校验如 NonNull 校验参数非空编译期直接报错框架核心Spring 的 Component 扫描、Dubbo 的 Service 注解文档生成自动生成 API 文档、接口文档。七、总结本文从原理、环境、实战、问题四个维度带你彻底掌握 Java 注解处理器注解处理器是编译期工具无运行时性能损耗核心步骤自定义注解 → 开发处理器 → SPI 配置 → 编译自动生成代码配合 JavaPoet可快速实现代码生成极大提升开发效率是框架开发、代码优化的必备技能。注解处理器是 Java 进阶的核心知识点吃透它你就能读懂大部分框架的底层原理甚至开发自己的代码生成工具

相关文章:

深入浅出 Java 注解处理器:从原理到实战,一键生成代码

在日常 Java 开发中,你一定用过Override、Autowired、Data这些注解,它们极大简化了代码开发。但你有没有想过,Lombok 是如何通过一个 Data 就自动生成 get/set 方法?MyBatis-Plus 的代码生成器、Spring 的依赖注入,底层…...

书匠策AI:文献综述写作的“魔法画笔”,绘就学术新蓝图

在学术的浩瀚宇宙中,每一篇论文都是一颗独特的星辰,而文献综述则是这颗星辰的“导航图”,指引着研究的方向,照亮前行的道路。然而,对于许多研究者来说,撰写文献综述却如同在茫茫星海中寻找特定的星座&#…...

Hunyuan-MT ProGPU算力适配:FP8量化实验与翻译质量衰减阈值报告

Hunyuan-MT Pro GPU算力适配:FP8量化实验与翻译质量衰减阈值报告 1. 项目背景与实验意义 Hunyuan-MT Pro是基于腾讯混元大模型构建的专业级翻译工具,在实际部署中面临着一个关键挑战:GPU显存占用过高。使用标准的bfloat16精度加载模型需要1…...

Hunyuan-MT-7B翻译模型部署与使用全攻略:小白也能快速上手

Hunyuan-MT-7B翻译模型部署与使用全攻略:小白也能快速上手 1. 为什么选择Hunyuan-MT-7B? 在当今全球化时代,语言障碍仍然是许多企业和个人面临的挑战。Hunyuan-MT-7B作为腾讯混元系列的开源翻译模型,凭借其卓越的性能和易用性&a…...

JavaScript 前端优化:实现 Z-Image-Turbo-rinaiqiao-huiyewunv 生成结果的实时流式预览

JavaScript 前端优化:实现 Z-Image-Turbo-rinaiqiao-huiyewunv 生成结果的实时流式预览 你有没有遇到过这种情况?在网页上点击生成一张图片,然后就是漫长的等待,屏幕上一个旋转的圆圈,或者一个进度条,你完…...

终极指南:OpenDrop项目文档生成工具对比——Sphinx vs MkDocs vs pdoc

终极指南:OpenDrop项目文档生成工具对比——Sphinx vs MkDocs vs pdoc 【免费下载链接】opendrop An open Apple AirDrop implementation written in Python 项目地址: https://gitcode.com/gh_mirrors/op/opendrop OpenDrop作为一款用Python实现的开源Apple…...

RexUniNLU在算法竞赛题目理解中的辅助应用

RexUniNLU在算法竞赛题目理解中的辅助应用 算法竞赛选手的福音:让AI帮你秒懂题目要求,告别理解偏差导致的WA 作为一名算法竞赛选手,你是否曾经因为题目理解偏差而错失AC?那些冗长的题目描述、复杂的输入输出格式、隐蔽的边界条件&…...

【软考 位示图大小计算问题】物理块|字长|字数

文章目录 【操作系统必考】位示图(Bitmap)大小计算 超全题型解题模板一、位示图基本概念(考试必背)1. 什么是位示图2. 核心公式(万能模板) 二、单位换算(考试最容易丢分点)三、经典例…...

基于单片机的自动门系统(有完整资料)

资料查找方式:特纳斯电子(电子校园网):搜索下面编号即可编号:T1552204C设计简介:本设计是基于单片机的自动门系统,主要实现以下功能:1.利用红外线感应器和温度传感器准确的收集数据。…...

CLIP-GmP-ViT-L-14GPU算力适配:A10/A100/T4多卡推理吞吐量实测对比

CLIP-GmP-ViT-L-14 GPU算力适配:A10/A100/T4多卡推理吞吐量实测对比 当你手头有不同型号的GPU,比如A10、A100或者T4,想把一个像CLIP-GmP-ViT-L-14这样的视觉语言大模型跑起来,心里肯定会有几个问号:用哪张卡最划算&am…...

如何确保LLVM项目的长期技术可持续性:开源代码库维护的完整指南

如何确保LLVM项目的长期技术可持续性:开源代码库维护的完整指南 【免费下载链接】llvm-project llvm-project - LLVM 项目是一个编译器和工具链技术的集合,用于构建中间表示(IR)、优化程序代码以及生成机器代码。 项目地址: https://gitcode.com/GitHu…...

LLVM编译优化如何提升工业控制系统实时响应性能:5大关键技术解析

LLVM编译优化如何提升工业控制系统实时响应性能:5大关键技术解析 【免费下载链接】llvm-project llvm-project - LLVM 项目是一个编译器和工具链技术的集合,用于构建中间表示(IR)、优化程序代码以及生成机器代码。 项目地址: https://gitcode.com/GitH…...

React Error Boundary 终极升级指南:6.0版本平滑迁移完整清单

React Error Boundary 终极升级指南:6.0版本平滑迁移完整清单 【免费下载链接】react-error-boundary Simple reusable React error boundary component 项目地址: https://gitcode.com/gh_mirrors/re/react-error-boundary React Error Boundary 是 React 应…...

AudioSeal入门必看:水印密钥管理、私钥保护与多租户隔离实践建议

AudioSeal入门必看:水印密钥管理、私钥保护与多租户隔离实践建议 1. 项目概述 AudioSeal是Meta开源的语音水印系统,专门用于AI生成音频的检测和溯源。这套系统通过独特的水印技术,能够在音频中嵌入可检测的数字指纹,帮助识别音频…...

掌握AWS SDK for JavaScript (v2) 依赖管理:package.json核心依赖完整指南

掌握AWS SDK for JavaScript (v2) 依赖管理:package.json核心依赖完整指南 【免费下载链接】aws-sdk-js AWS SDK for JavaScript in the browser and Node.js 项目地址: https://gitcode.com/gh_mirrors/aw/aws-sdk-js AWS SDK for JavaScript (v2) 是浏览器…...

用Wan2.2-I2V-A14B为你的照片注入生命:创意短视频制作全流程

用Wan2.2-I2V-A14B为你的照片注入生命:创意短视频制作全流程 1. 引言:让静态照片动起来 你是否曾看着手机里的照片,想象它们能像电影一样动起来?现在,借助Wan2.2-I2V-A14B这款强大的视频生成模型,这个梦想…...

GLM-Image多场景落地:AI辅助建筑设计概念图与室内渲染效果图生成

GLM-Image多场景落地:AI辅助建筑设计概念图与室内渲染效果图生成 1. 引言:当AI画笔遇见建筑蓝图 想象一下,你是一位建筑师或室内设计师。客户刚刚描述了一个模糊的概念:“我想要一个现代简约风格的客厅,要有大落地窗…...

Qwen-Image镜像真实效果:RTX4090D对遮挡/旋转/低分辨率图像的稳健理解能力

Qwen-Image镜像真实效果:RTX4090D对遮挡/旋转/低分辨率图像的稳健理解能力 1. 开篇:认识Qwen-Image定制镜像 Qwen-Image定制镜像是专为RTX 4090D显卡优化的多模态大模型推理环境,预装了完整的CUDA 12.4驱动和通义千问视觉语言模型&#xff…...

Qwen3.5-9B实操入门:Gradio界面操作+提示词工程+结果可视化全链路

Qwen3.5-9B实操入门:Gradio界面操作提示词工程结果可视化全链路 1. 快速了解Qwen3.5-9B Qwen3.5-9B是阿里云推出的新一代多模态大语言模型,在视觉-语言理解和推理能力上实现了显著提升。与上一代产品相比,它采用了创新的混合架构设计&#…...

Qwen3-32B大模型GPU部署指南:RTX4090D显存碎片化问题与clean_cache策略

Qwen3-32B大模型GPU部署指南:RTX4090D显存碎片化问题与clean_cache策略 1. 镜像概述与环境准备 1.1 镜像基本信息 本镜像专为RTX 4090D 24GB显存显卡优化,包含以下核心组件: 基础模型:Qwen3-32B-Chat最新版本适配硬件&#xf…...

3步搞定Chandra本地部署:VSCode开发环境配置全攻略

3步搞定Chandra本地部署:VSCode开发环境配置全攻略 如果你正在寻找一个能快速上手、完全私有化的AI聊天助手,Chandra可能就是你需要的那个工具。它把整个AI对话系统打包成一个镜像,从模型运行到界面交互,全部可以在你自己的设备上…...

掌握PureLayout:轻松实现深色模式下的完美布局适配

掌握PureLayout:轻松实现深色模式下的完美布局适配 【免费下载链接】PureLayout The ultimate API for iOS & OS X Auto Layout — impressively simple, immensely powerful. Objective-C and Swift compatible. 项目地址: https://gitcode.com/gh_mirrors/p…...

企业SRC漏洞挖掘(赏金)技巧(非常详细),零基础

限时分享!企业SRC漏洞挖掘(赏金)技巧(非常详细),零基础入门到精通,看这一篇就够了 前言: **使用说明:**本篇文章旨在提供网络安全技术研究的信息和知识,以供信息技术专业人士、学者…...

Qwen3.5-9B效果展示:Qwen3.5-9B在ChartQA图表问答任务中92.7%准确率实测

Qwen3.5-9B效果展示:Qwen3.5-9B在ChartQA图表问答任务中92.7%准确率实测 1. 惊艳的图表理解能力 当第一次看到Qwen3.5-9B解析复杂图表并准确回答问题的场景时,确实让人感到震撼。这个模型在ChartQA基准测试中达到了92.7%的惊人准确率,这意味…...

Qwen3.5-35B-AWQ-4bit镜像免配置优势解析:无Clash残留、服务重启自恢复实测

Qwen3.5-35B-AWQ-4bit镜像免配置优势解析:无Clash残留、服务重启自恢复实测 1. 开箱即用的多模态AI体验 Qwen3.5-35B-AWQ-4bit是一款面向视觉多模态理解的量化模型,它让复杂的图片分析和图文对话变得像聊天一样简单。想象一下,你只需要上传…...

Qwen-Image企业实操:金融文档图像+文字联合推理的合规审查应用

Qwen-Image企业实操:金融文档图像文字联合推理的合规审查应用 1. 金融合规审查的痛点与解决方案 在金融行业,合规审查是一项耗时耗力的重要工作。传统的人工审查方式面临三大挑战: 效率低下:一份50页的合同需要2-3小时人工审核…...

如何利用dc.js打造智慧城市公共服务数据可视化平台:从入门到实践指南

如何利用dc.js打造智慧城市公共服务数据可视化平台:从入门到实践指南 【免费下载链接】dc.js Multi-Dimensional charting built to work natively with crossfilter rendered with d3.js 项目地址: https://gitcode.com/gh_mirrors/dc/dc.js 在当今数字化时…...

LingBot-Depth在Java学习路线中的实践项目

LingBot-Depth在Java学习路线中的实践项目 1. 项目概述 想象一下,你正在学习Java编程,已经掌握了基础语法和面向对象的概念,但总觉得缺少一个能把这些知识串起来的实战项目。传统的学生管理系统或图书管理系统已经无法激发你的兴趣&#xf…...

7个ReSwift项目结构最佳实践:Swift状态管理的终极指南

7个ReSwift项目结构最佳实践:Swift状态管理的终极指南 【免费下载链接】ReSwift ReSwift/ReSwift: ReSwift是基于Swift语言构建的状态管理库,灵感来源于Redux模式。通过引入单向数据流和可预测状态变更的理念,ReSwift使得在Swift应用中管理和…...

2025后端远程工作时间管理指南:GitHub加速计划社区经验总结

2025后端远程工作时间管理指南:GitHub加速计划社区经验总结 【免费下载链接】vagas Espao para a divulgao de vagas para desenvolvedores backend via issues do Github. 项目地址: https://gitcode.com/gh_mirrors/vag/vagas GitHub加速计划(v…...