Lombok 实现原理是什么?

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论

  • 新项目:《从零手撸:仿小红书(微服务架构)》 正在持续爆肝中,基于 Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...点击查看项目介绍
  • 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/

截止目前, 星球 内专栏累计输出 80w+ 字,讲解图 3365+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 2700+ 小伙伴加入学习 ,欢迎点击围观

前面《Lombok 注解》 一章中,我们已经熟悉了 Lombok 相关注解,以及使用方法。你可能会好奇, Lombok 的实现原理是什么?Lombok 是如何魔力般地简化我们的 Java 代码的呢?本小节中,我们就来说说其实现原理。

核心实现原理

Lombok 的核心是利用 Java 注解处理器AST(抽象语法树)修改 技术,在编译阶段动态插入代码

1. 注解处理器

Java 的 javax.annotation.processing 包提供了注解处理器的支持。Lombok 使用该机制,通过实现 AnnotationProcessor 接口来处理注解。

Lombok 编译时注解处理的流程如下:

  1. 注解扫描:Java 编译器在编译过程中扫描所有类上的注解,如果找到 Lombok 的注解(如 @Getter@Setter 等),会将这些注解交给 Lombok 处理。

  2. 注解处理:Lombok 自定义的注解处理器会在处理阶段解析这些注解,识别哪些注解需要生成代码。

  3. 修改 AST:Lombok 的注解处理器会读取编译器生成的 AST 树,针对特定注解修改或新增相应的代码节点,例如,针对 @Getter 注解,Lombok 会在类的 AST 中插入 get 方法。

  4. 字节码生成:经过修改的 AST 树会继续传递给 Java 编译器,编译器会根据更新后的 AST 生成新的字节码文件。

2. AST 操作

AST 是源代码结构的树状表达形式。Lombok 使用 Java 编译器中不同阶段的 AST 解析结果来完成代码的插入操作。具体来说,Lombok 通过对 Java 编译器的扩展,直接操作 AST 来实现以下功能:

  • 方法添加:Lombok 通过注解生成 gettersetter 等方法,将方法节点插入到 AST 树中。
  • 构造器生成:针对 @AllArgsConstructor@NoArgsConstructor 等注解,Lombok 会自动在 AST 树中创建构造器节点。
  • 字段操作:对于不可变对象的 @Value 注解,Lombok 会将字段设置为 final

3. 编译器适配

Lombok 需要对不同的 Java 编译器进行适配,如 Eclipse 的 ECJ 编译器和 javac 编译器。Lombok 提供了适配层,分别处理 Eclipse 和 IDEA 编译环境下的代码生成。Lombok 实现了对这两个编译器的底层 AST 操作,因此无论是在 Eclipse 还是 IDEA 中都能使用 Lombok 功能。

在不同 IDE 下的适配机制如下:

  • Eclipse:Eclipse 使用 ECJ(Eclipse Compiler for Java)编译器,Lombok 通过操作 Eclipse 的内部编译 API 来修改 AST。
  • IntelliJ IDEA:IDEA 使用 javac 编译器,Lombok 通过 JavacTreeMaker 操作 javac 的 AST 树节点。

4. 编译期间字节码插桩

Lombok 通过编译器插件机制和字节码插桩实现代码的生成。它不需要依赖类加载器,也不会在运行时修改字节码,因此没有额外的性能开销。Lombok 修改的是 编译期间的字节码,因此生成的 .class 文件中已包含所有注解生成的代码,不需要在运行时引入 Lombok 依赖。

优缺点

优点

  • 减少样板代码:Lombok 大幅减少了 Java 中大量的样板代码,如 getter/setter、构造器、toStringequals 等。
  • 提高开发效率:通过注解简化代码书写,提升了开发效率和代码可读性。
  • 编译期优化:Lombok 的代码生成在编译期完成,不会影响运行时性能。

缺点

  • 编译器适配:Lombok 依赖于对编译器的深度集成和 AST 操作,不同的 IDE 和编译环境可能需要特殊配置和适配。
  • 代码可见性差:Lombok 自动生成代码在 IDE 中不可见,可能会影响代码调试和理解,尤其是对新手而言。
  • 依赖限制:Lombok 是第三方库,尽管已经很成熟,但在某些特定环境下可能会与其他编译器插件或框架发生冲突。

小结

Lombok 通过注解处理器和 AST 修改技术在编译期动态生成代码,帮助开发者减少样板代码的书写,提高开发效率。它在编译期间完成所有代码生成,并不会影响程序运行时的性能。然而,Lombok 的使用也存在一些不足,特别是代码可见性和编译器适配问题。