领先一步
VMware提供培训和认证,以加速您的进步。
了解更多我们在Spring Boot 2.3.0.M1中做了一个相当大的改动。这是该项目第一个使用Gradle而不是Maven构建的版本。关于迁移的Twitter帖子中,很多人都在问我们为什么切换以及我们看到了哪些好处(如果有的话)。这篇博文旨在解答这些问题。
Spring产品组合中的每个项目都是以相当自主的方式运行的。我们努力在用户最能看到的地方保持一致性——例如API设计——但在选择工具方面,则选择最能满足项目需求的工具,而这些工具在很大程度上是不可见的。构建系统就是一个例子。构建系统的更改会影响项目的贡献者,但如果我们做对了,它不会对用户产生任何影响。这导致了Maven和Gradle构建的混合使用。例如,Spring Framework自2012年的3.2.0.M1版本以来就一直使用Gradle构建,而Spring Boot一年后开始使用,Spring Cloud紧随其后,两者都使用基于Maven的构建。与Spring Boot不同,Spring Cloud没有切换的计划,因为Maven继续满足他们的需求。简而言之,如果您只从这篇博文中汲取一件事情,那就是您应该选择最能满足项目需求的工具。
Spring Boot团队考虑切换到Gradle的主要原因是减少项目构建所需的时间。我们越来越厌烦在进行和测试更改时反馈循环的长度。等待构建完成所花费的时间增加了修复错误和实现新功能所需的时间。我们在其他Spring项目中看到了Gradle增量和并行构建的好处,以及在第三方项目中Gradle构建缓存的好处。我们希望我们能在Spring Boot的构建中获得类似的好处。
我们过去曾尝试利用Maven对并行构建的支持。由于Spring Boot构建的复杂性,特别是它对Invoker插件的使用,我们的尝试失败了。我们在CI中通过将构建分成四个部分来解决这个问题。项目的主要核心首先构建,然后三个独立的部分并行构建。这种安排有所帮助,但CI构建仍然需要一个小时或更长时间。此外,由于拆分结构特定于CI构建,因此它并没有使开发人员的本地构建速度更快。
Gradle具有构建结构的广泛模型,理解每个任务及其相互依赖关系的输入和输出。这个模型的承诺是它允许并行运行任务,同时也能进行增量、缓存或完全避免任务。换句话说,Gradle旨在最大限度地减少构建任何给定更改所需的工作量,并并行执行所需的工作。如果我们坚持并广泛重构Spring Boot的构建,那么使用Maven进行并行构建可能是可能的。而且,如果我们使用了Gradle Enterprise的Maven支持,我们也可以享受到构建缓存和避免的好处。但是,为了充分利用所有四个方面的优势,我们觉得我们必须尝试切换到Gradle。
我们看到的一个对Gradle的批评是,它导致的构建比基于Maven的等效构建更难维护和理解。Gradle的灵活性允许即使在同一构建中的模块之间也能以细微不同的方式完成工作。如果切换要成功,我们需要避免这种情况。在使用Gradle发布了四个Spring Boot 2.3里程碑、它的候选版本和最终版本之后,看起来我们已经成功了。我们在核心团队或任何其他贡献者那里都没有看到任何主要的构建问题。
Spring Boot的一个关键特性是约定优于配置,我们也将其应用于构建。遵循避免在build.gradle
文件中使用命令式逻辑的建议,我们编写了几个可以在项目buildSrc
中找到的小插件。例如,我们有一个启动器插件,它应用于每个Spring Boot启动器模块,确保它们都一致地配置、构建和发布。我们还有一个约定插件,它会对其他插件的应用做出反应,并配置诸如源代码编码、JUnit平台的使用以及使用-parameters
编译等内容。
这种方法导致build.gradle
文件几乎完全是声明式的。即使我们编写了许多插件来应用我们的约定并填补Gradle生态系统中的空白,迁移到Gradle的提交从代码库中删除了近9500行代码。
在减少项目构建时间方面,将构建迁移到Gradle无疑是成功的。如上所述,基于Maven的完整构建在CI和开发人员自己的机器上都需要一个小时或更长时间。在过去四周中,使用Gradle的平均成功构建时间为9分钟22秒,如下图所示
我们从JDK 8 CI构建中发布快照。关注这些快照,在过去四周内,它成功了183次,平均构建时间为19分钟37秒。查看成功的本地构建,我们可以看到在过去四周内有273次成功的构建,平均构建时间为2分钟30秒。
另一个吸引我们使用Gradle的好处是我在为Testcontainers做贡献时所享受的经验。我们也希望Spring Boot的贡献者能够尽快克隆和构建项目。由于远程构建缓存,干净的检出可以在3分钟内构建。这包括下载大量依赖项所花费的时间。
如果您想了解有关构建性能的更多详细信息,我们的公共Gradle Enterprise实例上提供了更多数据。
除了性能改进之外,我们还开始关注一些其他可用数据。例如,我们已经意识到一段时间以来,我们有很多不稳定的测试。由于这些测试,构建失败的频率比我们想要的要高,我们现在可以看到这反映在测试仪表板中。我们已开始使用Gradle的不稳定测试缓解功能来识别CI上发生的所有不稳定测试,并帮助我们了解我们是否已成功解决或规避了这些问题。
我们对迁移的进展以及我们看到的构建时间减少感到非常满意。CI构建现在平均大约需要20分钟,比以前快3-4倍。本地构建平均需要2分钟30秒,比以前快20-30倍。
借此机会感谢Gradle团队在迁移期间提供的帮助,并感谢他们慷慨地为我们的开源项目提供Gradle Enterprise许可证。我们已经在Spring Framework、Spring Security和Spring Boot中使用它,其他团队也计划开始将其用于基于Gradle和Maven的构建。
我还想感谢我们正在使用的各种第三方插件的维护者。他们提出了建议的更改并合并了拉取请求以改进对增量构建和缓存的支持。没有他们,我们就无法实现我们看到的构建时间减少。
如果您正在考虑从Maven迁移到Gradle,我希望了解Spring Boot团队的经验能有所帮助。如果您是快乐的Maven用户,请继续使用并支持对您有效的工具。