在 2.3.0 中对 Spring Boot 进行了相当重大的更改,这是使用 Gradle 而非 Maven 构建的项目的个版本。
Spring 的每个项目都独立的项目组在开发运营,在用户常使用的白盒部分(例如 API 设计)保持一致性,对于用户不可见的黑盒部分,各个项目组选择自己适合工具没有统一的约定。
例如: 项目构建工具。Spring Framework 自 2012 年的 3.2.0 起就使用 Gradle 构建,而一年后开始使用 Spring Boot,此后不久又开始使用 Spring Cloud,两者都基于 Maven。
项目 | 构建工具 |
---|---|
Spring Framework | Gradle |
Spring Boot | Maven |
Spring Cloud | Maven |
为什么要切换
Spring Boot 团队考虑由 Maven 切换到 Gradle 的主要原因为了减少构建项目所需的时间。在开发和测试过程中,等待构建完成所花费的时间增加了修复错误和实现新功能所花费的时间。
为了解决这个问题,团队曾尝试利用 Maven 对并行构建的支持。由于 Spring Boot 构建的复杂性,特别是对 Invoker 插件的使用,尝试失败。通过将构建分为四个部分来解决 CI 问题。首先构建项目的主要核心,然后并行构建三个独立的部分。但 CI 的构建仍需要一个小时或更长时间。此外,由于针对的是模块化 CI 构建,因此并没有使得开发人员本地构建效率有所改变。
Spring Boot 团队在其他利用 Gradle 作为构建工具的 Spring 项目中看到了 Gradle 的增量和并行构建以及在第三方项目中看到了 Gradle 的构建缓存的好处。希望通过使用 Gradle 为 Spring Boot 构建获得类似的好处。
Gradle 具有非常灵活的构建模型,并且可以定义每个任务的输入和输出及其相互依赖性。这种构建模型的好处是,它允许任务并行运行,同时也可以增量、缓存或完全跳过。换句话说,Gradle 可以小化的执行必要的 CI 任务。虽然可以使用了 Gradle Enterprise 的 Maven 支持,我们也可以享受构建缓存和跳过的好处。但是要充分享受这四个方面的好处,必须尝试切换到 Gradle。
如何切换
Gradle 配置过于灵活,导致它的构建比基于 Maven 构建更难以维护和理解。例如: 同一个构建结果,可以通过不同的配置实现。如果切换到 Gradle,需要避免这种情况。从目前发布的四个 Spring Boot 2.3 里程碑版本,在核心团队或贡献者中,还没有发现任何重大的构建问题。
- Spring Boot 关键功能是约定优于配置,将这种方法应用于构建。避免在 build.gradle 文件中包含命令式逻辑,编写了几个可以在项目的中找到的小插件 buildSrc。。
虽然现有 Gradle 生态系统对 Spring Boot 构建几乎空白,需要从头通过编写很多通用的 gradle 插件来应用到 Spring Boot,但迁移到 Gradle 的提交从代码库中删除了近 9500 行。
切换结果
就减少项目构建时间而言,将构建迁移到 Gradle 无疑是成功的。如上所述,在 CI 和开发人员机器上,基于 Maven 的完整构建都需要一个小时或更长时间。而基于 Gradle 的平均成功构建时间为 9 分 22 秒,如以下截图所示:
如果对构建性能的更多细节感兴趣,可以在 Spring Boot 的公共Gradle Enterprise实例上获得更多数据。
除了提高性能外,对其他功能进行探索。例如,一段时间以来,进行许多不稳定的测试。由于这些原因,构建失败的次数比预期要多,可以在 Tests 仪表板中看到这一点。使用 Gradle 分片测试来替代 CI 的通用测试方案,并帮组我们了解是否已成功解决问题。
结论
CI 构建现在平均大约需要 20 分钟,比以前快 3-4 倍。
本地构建平均需要 2 分钟 30 秒,比以前快 20-30 倍。
migrating-spring-boot-s-build-to-gradle
Gradle 在随行付标准化实践:一行代码带来的变革!