Project Lombok
  • 功能
    • 稳定
    • 实验性
  • 社区
    • 讨论 / 帮助
    • 问题
    • 贡献者文档
    • 联系 Project Lombok 团队
  • 订购 / 捐赠
  • 如何使用 安装
    • 编译器
    • Javac
    • ECJ
    • 构建工具
    • maven
    • gradle
    • ant
    • kobalt
    • IDEs
    • Eclipse
    • IntelliJ IDEA
    • Netbeans
    • MyEclipse
    • Spring Tool Suite
    • JBoss Developer Studio
    • Visual Studio Code
    • 平台
    • Android
    • GWT
  • 下载

Lombok 执行路径

Javac:作为注解处理器启动

使用 javac(以及 netbeans、maven、gradle 和大多数其他构建系统),lombok 作为注解处理器运行。

Lombok 在类路径上,并且 javac 将加载类路径上找到的每个 META-INF/services/javax.annotation.processing.Processor 文件,读取每一行并加载该类,然后将其作为注解处理器执行。lombok.jar 包含此文件,其中列出了 lombok.launch.AnnotationProcessorHider$AnnotationProcessor 作为入口。

这个类实际上是不可见的(它是公共的,但它的外部类 (AnnotationProcessorHider) 是包私有的,这使得它对于 java 语言是不可见的),但是,为了 java-the-VM 的目的,它被认为是可见的,因此它将运行。这个复杂的技巧用于确保任何在类路径上使用 lombok 进行开发的人都不会将 lombok 的类或 lombok 的依赖项注入到他们的“命名空间”中(例如,如果您将 lombok 添加到您的项目中,您的 IDE 将不会开始为自动完成对话框建议 lombok 类)。

lombok.launch.AnnotationProcessorHider$AnnotationProcessor 类由 javac 加载、实例化,并调用其 init() 方法。这个类启动了 lombok 的 ShadowClassLoader;它找到它所在的 jar 文件,然后将开始从这个 jar 文件加载类。它不像普通的加载器那样查找以 .class 结尾的文件,而是查找以 .SCL.lombok 结尾的文件(这也是为了将 lombok 的类从 IDE 等隐藏起来)。通过这个类加载器,启动了真正的注解处理器,即 lombok.core.AnnotationProcessor 类。

lombok.core.AnnotationProcessor 也是一个委托处理器。它可以根据 lombok 自身所处的环境委托给 2 个子处理器之一:如果是 javac,则使用 lombok.javac.apt.LombokProcessor 类(如果使用 plexus 编译器框架,这在使用 javac 编译时可能会发生,则会运行一些额外的代码来将 lombok 补丁到其模块化类加载架构中)。如果是 ecj(eclipse 的编译器,这意味着我们要么在 eclipse 内部运行,要么作为 ecj 的注解处理器被调用,即独立的 eclipse 编译器),则会向编译过程中注入错误/警告,以告知用户他们应该使用不同的参数来在 eclipse/ecj 中使用 lombok。

lombok.javac.apt.LombokProcessor 是“真正的”注解处理器,它负责转换您的代码。

代码转换从根本上来说是一个循环概念:要生成一些代码,您需要了解代码(例如,其中有哪些注解),但是当您生成新代码时,解释它意味着我们重新开始。这同样适用于 lombok 本身:lombok 的某些转换会添加方法,这些方法随后会对其他 lombok 转换产生影响。因此,lombok 将处理程序划分为“级别”。执行最高级别的所有处理程序,然后强制进行新的注解轮次(这将生成的内容集成到符号表等中),然后再执行下一级别的处理程序。这些级别通过 @HandlerPriority 注解指示。您通过生成文件来强制 javac 运行另一轮。我们实际上不想生成任何文件,因此我们生成一个虚拟文件并修补 javac filer 以实际上不将 lombok 生成的虚拟文件保存到任何地方。应用实际 lombok 转换的各种 HandleX 类存储在 HandlerLibrary 中,后者使用 SPI 来发现处理类。

Eclipse/ECJ:作为代理启动

使用 ecj 和 eclipse,lombok 作为“代理”启动。这有点像调试器:它让 lombok 在 JVM 实际加载这些类之前检查原始类字节码,并且 lombok 将修改此代码以确保 ecj/eclipse 在编译过程中包含 lombok。

类的修补由 src/eclipseAgent 源代码目录中的代码完成。请注意,修补代码必须修补 equinox,即 eclipse 模块系统,以确保 lombok 和 java 编译模块(在 eclipse 术语中为“JDT”模块)可以相互看到。

应用了许多针对问题的临时修复(例如,eclipse 的代码格式化功能需要一些战术性的字节码补丁,以确保它不会搞乱格式化源),但注入到 ecj/eclipse 中的主要“将 lombok 作为编译过程的一部分运行”钩子指向了 lombok.eclipse.TransformEclipseAST 类,这可以被认为是入口点。除非您想弄乱 lombok 如何加载到 eclipse/ecj 中,否则从这里开始。

每个 HandleX 类都通过 SPI 发现,lombok 将根据需要调用处理类。处理类查找 lombok 注解并应用所需的转换。处理程序位于 src/core 源代码目录的 lombok.eclipse.handlers 包中。

VSCode 和 IntelliJ:作为插件启动

Lombok 在这两个 IDE 中的支持由这些 IDE 的插件负责。

鸣谢 | 版权所有 © 2009-2024 The Project Lombok Authors,根据 MIT 许可证 授权。