初识Lombok

前言

最近读一些公司的业务代码,发现近几年的java项目工程中都使用了lombok,lombok是一个可以自动生成get,set、toString等模板类方法的工具框架,程序再引入lombok后,添加一个注解便可以不写get\set\toString等方法。

Lombok示例

1、pom.xml中引入依赖

		<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.2.3</version></dependency>

2、一个简单的pojo类

@Getter
@Setter
public class Student {private String name;private int age;
}

3、使用

 @Testpublic void test1(){Student student = new Student();student.setName("cz");student.setAge(12);System.out.println(student.getAge());System.out.println(student.getName());}

效果:
在这里插入图片描述

原理分析

通过以上测试案例可以看出,源码中并没有setName()和getName()方法,但是调用后并没有报错,反而运行成功了。那咱们大胆的猜测一下,会不会是在运行或者编译时动态的生成了代码?那么假设是运行时生成了代码,那大概率会使用到ASM或者其他字节码框架。但是这样编译阶段必然会报错,因为java是先编译后运行的。排除了第一种假设之后,我们只能按照第二种猜测来探究一下了。

首先从注解入手。

1、注解的种类

开发过程中经常用到注解,有时也会自定义注解,注解一般有两个重要的参数,一个是注解的作用域(Target)另一个是注解的保留策略(Retention),其中Retention有三个枚举分别如下:
1、SOURCE 表示注解只在源码阶段保留,编译成class后将不保留
2、CLASS 表示编译为class后也保留该注解,但是该注解运行时不能通过calzz.getAnnotation()获取到。
3、RUNTIME 表示class文件中保留该注解,同时也能使用getAnnotation获取到注解信息。

我在开发过程中一般使用的都是RUNTIME。
在这里插入图片描述

2、java编译器

《深入理解java虚拟机:JVM高级特性与最佳实践》这本书中描述了编译的几个关键步骤:
1、准备过程:初始化插入式注解处理器
2、解析与符号填充
3、插入式注解处理器的处理过程
4、分析与字节码的生成过程

其中上述的注解其实就是带有Retention(RetentionPolicy.SOURCE)保留策略的注解。Lombok的原理看到这里心里应该有了一个大概的认识了,lombok就是利用插入式注解同时自定义了注解处理器来干扰编译过程同时生成了目标代码。
在这里插入图片描述

3、java SPI机制

前文通过《深入理解java虚拟机》这本书了解到了lombok是如何通过注解来生成代码的,但是我还是有个疑问,lombok自定义的注解处理器是如何被程序找到并执行的呢? 答案就是Java的SPI机制。

SPI机制是JDK提供的一个服务发现机制,但是注意这里的服务发现机制并不是在分布式开发中接触到的类似zookeeper的服务注册和发现的中间件,而是一个针对本地interface接口的服务发现机制。下面用一个简单的例子展示一下。

3.1 编写接口
public interface TestSpiService {public void say();
}
3.2 编写实现类
public class TestSpiServiceImpl implements TestSpiService{@Overridepublic void say() {System.out.println("我说了一句话");}
}
3.3 注册接口

注意图中的文件路径(META-INF/services)和文件名称(接口的全路径做为文件名称)和配置内容(接口实现类的全路径)在这里插入图片描述

3.4 接口调用
public class Main {public static void main(String[] args) {ServiceLoader<TestSpiService> loader = ServiceLoader.load(TestSpiService.class);for (TestSpiService spiService : loader) {spiService.say();}}
}

Lombok是如何指定自定义注解处理器的?

通过上述案例,我们发现可以通过配置文件的方式指定接口的实现类,同理JDK也是使用了这样的方式为自定义注解处理器提供了条件,再来看一下JDK中注解处理器准备阶段的源码(下图),从源码可以看到JDK也是使用了SPI机制来获取注解处理器。

在这里插入图片描述
看到这里我猜测lombok源码中也应该有一个META-INF/services文件夹同时在文件夹中存在avax.annotation.processing.Processor文件用来指定@Getter、@Setter等等自定义的注解处理器实现类。可是当我打开源码翻了所有的文件并没有找到META-INF文件夹。但是在一个构建脚本中发现了秘密,原来源码构建打包为jar包时在生成的jar包中才会生成该文件。
在这里插入图片描述
知道了自定义注解以及注解处理器的实现后,我又想到了JDK自带的几个注解,比如@Override(方法重写)会不会也是通过SPI来指定处理器处理的?其实JDK自带的几个注解并没有使用SPI机制实现,而是直接处理的。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2809324.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

DALL-E 系列 (1-3)

DALL-E 系列 (1-3) 本文主要梳理 DALL-E 系列图像生成模型的整体框架&#xff0c;相关论文中都包含了丰富的训练、优化细节&#xff0c;对这些细节本文不做过多介绍&#xff0c;有兴趣的读者可以阅读原文。注意&#xff0c;在阅读本文之前&#xff0c;最好先了解 VAE、VQVAE、…

SQL进阶(三):Join 小技巧:提升数据的处理速度

复杂数据结构处理&#xff1a;Join 小技巧&#xff1a;提升数据的处理速度 本文是在原本sql闯关的基础上总结得来&#xff0c;加入了自己的理解以及疑问解答&#xff08;by GPT4&#xff09; 原活动链接 用到的数据&#xff1a;链接 提取码&#xff1a;l03e 目录 1. 课前小问…

静态时序分析:SDC约束命令set_load详解

相关阅读 静态时序分析https://blog.csdn.net/weixin_45791458/category_12567571.html?spm1001.2014.3001.5482 set_load命令用于指定端口(port)或线网(net)的负载电容&#xff0c;该指令的BNF范式&#xff08;有关BNF范式&#xff0c;可以参考以往文章&#xff09;为&#…

锂电池SOC估计 | PyTorch实现基于Basisformer模型的锂电池SOC估计

目录 预测效果基本介绍程序设计参考资料 预测效果 基本介绍 PyTorch实现基于Basisformer模型的锂电池SOC估计 锂电池SOC估计&#xff0c;全新【Basisformer】时间序列预测 1.采用自适应监督自监督对比学习方法学习时序特征&#xff1b; 2.通过双向交叉注意力机制计算历史序列和…

计算机网络面经-TCP的拥塞控制

写在前边 前边我们分享了网络分层协议、TCP 三次握手、TCP 四次分手。今天我们继续深入分享一下 TCP 中的拥塞控制。 对于 TCP 的拥塞控制,里边设计到很多细节,平平无奇的羊希望通过这一节能够将这部分内容串通起来,能够让你更深刻的记忆这部分内容。 思维导图 1、什么…

嵌入式学习 Day 23

一. 进程基本概念: 1.进程: 程序&#xff1a;存放在外存中的一段数据组成的文件 进程&#xff1a;是一个程序动态执行的过程,包括进程的创建、进程的调度、进程的消亡 2.进程相关命令: 1.top 动态查看当前系统中的所有进程信息&#xff08;根据CPU占用率排序&#xff09;…

Java/Python/Go不同开发语言基础数据结构和相关操作总结-GC篇

Java/Python/Go不同开发语言基础数据结构和相关操作总结 1. 常见gc方式1.1 gc判断对象是否存活1.2 引用计数法1.2 标记-清除算法1.3 复制算法1.4 标记-压缩算法1.5 分代收集算法 2. java的gc方式以及垃圾回收器2.1 gc方式2.1 gc回收器2.1.1 Serial收集器2.1.2 ParNew收集器2.1.…

成长优化算法(Growth Optimizer,GO)求解不闭合MD-MTSP(提供MATLAB代码)

一、成长优化算法介绍 成长优化算法&#xff08;Growth Optimizer&#xff0c;GO&#xff09;由Qingke Zhang等人于2023年提出&#xff0c;该算法的设计灵感来源于个人在成长过程中的学习和反思机制。学习是个人通过从外部世界获取知识而成长的过程&#xff0c;反思是检查个体…

手写myscrapy(五)

项目地址&#xff1a;https://gitee.com/wyu_001/myscrapy 我们继续完成返回的处理类 MyResponse的实现 先上类图&#xff1a; 主要功能&#xff1a; json() 方法解析返回的json格式内容&#xff0c;转换为 python 的json对象 xpath(&#xff09;方法解析返回的html格式的内…

LabVIEW和Python开发微细车削控制系统

LabVIEW和Python开发微细车削控制系统 为满足现代精密加工的需求&#xff0c;开发了一套基于LabVIEW和Python的微细车削控制系统。该系统通过模块化设计&#xff0c;实现了高精度的加工控制和G代码的自动生成&#xff0c;有效提高了微细车削加工的自动化水平和编程效率。 项目…

微服务-微服务Spring Security OAuth 2实战

1. Spring Authorization Server 是什么 Spring Authorization Server 是一个框架&#xff0c;它提供了 OAuth 2.1 和 OpenID Connect 1.0 规范以及其他相关规范的实现。它建立在 Spring Security 之上&#xff0c;为构建 OpenID Connect 1.0 身份提供者和 OAuth2 授权服务器产…

区分服务 DiffServ

目录 区分服务 DiffServ 区分服务的基本概念 区分服务 DiffServ 的要点 每跳行为 PHB DiffServ 定义的两种 PHB 区分服务 DiffServ 区分服务的基本概念 由于综合服务 IntServ 和资源预留协议 RSVP 都较复杂&#xff0c;很难在大规模的网络中实现&#xff0c;因此 IET…

挑战杯 基于机器学习与大数据的糖尿病预测

文章目录 1 前言1 课题背景2 数据导入处理3 数据可视化分析4 特征选择4.1 通过相关性进行筛选4.2 多重共线性4.3 RFE&#xff08;递归特征消除法&#xff09;4.4 正则化 5 机器学习模型建立与评价5.1 评价方式的选择5.2 模型的建立与评价5.3 模型参数调优5.4 将调参过后的模型重…

vulnhub靶场---->DOUBLETROUBLE: 1

详细思路 知识点1.网段探测2.nmap扫描3.目录扫描4.隐写5.上传木马文件6.awk提权 知识点 图片隐写----->steghide 密码爆破----->stegseek awk提权------>sudo awk BEGIN {system("/bin/bash")}1.网段探测 kali:192.168.0.131 靶机&#xff1a;192.168.0.1…

【小沐学QT】QT学习之Web控件的使用

文章目录 1、简介1.1 Qt简介1.2 Qt下载和安装1.3 Qt快捷键1.4 Qt帮助 2、QtWeb控件2.1 测试代码1&#xff08;QApplication&#xff09;2.2 测试代码2&#xff08;QApplicationQWidget&#xff09;2.3 测试代码3&#xff08;QApplicationQMainWindow&#xff09;2.4 测试代码4&…

Spring事务模板及afterCommit存在的坑

大家好&#xff0c;我是墨哥&#xff08;隐墨星辰&#xff09;。今天的内容来源于两个线上问题&#xff0c;主要和大家聊聊为什么支付系统中基本只使用事务模板方法&#xff0c;而不使用声明式事务Transaction注解&#xff0c;以及使用afterCommit()出现连接未按预期释放导致的…

AI赋能Oracle DBA:以自然语言与Oracle数据库互动

DBA AI助手&#xff1a;以自然语言与Oracle数据库互动 0. 引言1. AI赋能Oracle DBA的优势2. AI如何与Oracle数据库交互3. 自然语言查询的一些示例4. 未来展望 0. 引言 传统的Oracle数据库管理 (DBA) 依赖于人工操作&#xff0c;包括编写复杂的SQL语句、分析性能指标和解决各种…

项目解决方案:街道社区视频监控接入、汇聚和联网设计方案

目 录 一、客户需求 二、网络拓扑图 三、方案描述 四、系统配置 1、服务器配置 2、带宽配置 五、方案优势 1. 平台可堆叠使用 2. 支持主流接入协议 4. 多种终端显示 5. 客户端功能强大 6. 一机一档 一、客户需求 1&#xff0c;一个街道有十个社…

计算机设计大赛 深度学习图像风格迁移 - opencv python

文章目录 0 前言1 VGG网络2 风格迁移3 内容损失4 风格损失5 主代码实现6 迁移模型实现7 效果展示8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习图像风格迁移 - opencv python 该项目较为新颖&#xff0c;适合作为竞赛课题…

Linux环境基础开发工具使用篇(三) git 与 gdb

一、版本控制器-git 1.简单理解: ①git既是服务端&#xff0c;又是客户端 ②git会记录版本的变化 ③git是一个去中心化的分布式软件 git/gitee 是基于git仓库搭建的网站&#xff0c;让版本管理可视化 2.git 三板斧提交代码 查看安装的git版本 git--version 命令行提交代…