Spring Boot 3.0.0-M5 中的原生支持

工程 | Stéphane Nicoll | 2022 年 9 月 26 日 | ...

Spring 团队一直在为 Spring 应用的原生镜像支持而努力。在 Spring Native 实验项目在 Spring Boot 2 中孵化 3 年多后,原生支持将在 Spring Framework 6 和 Spring Boot 3 中进入通用可用(GA)阶段!

原生镜像为 Java 应用提供了近乎即时的启动时间和更低的内存消耗。最近发布的 Spring Boot 3.0.0-M5 版本标志着我们首次寻求更广泛社区对我们原生方案的反馈。如果您需要了解基础知识,请参阅 3 月下旬发布的 前期(Ahead Of Time)基础知识博客文章。您还可以了解 如何为 Spring Boot 3.0 准备您的应用

自 3 月以来发生了许多变化!我们通过在此过程中修复和改进原生支持,提高了与更多用例和库的兼容性。这篇博客文章详细介绍了您入门所需了解的内容。

构建您的第一个原生镜像

最简单的入门方法是从 https://start.spring.io 创建一个新项目。确保选择 Spring Boot 3.0.0-M5(或更高版本)以及您喜欢的构建工具。完成此操作后,一种构建原生镜像的方法是使用 Native Build Tools 插件和本地 GraalVM 安装。

按照 说明安装 GraalVM,或者如果您安装了 SDKMan!,则调用以下命令

$ sdk install java 22.2.r17-nik

您可以通过确保 native-image 在您的路径中来检查一切是否按预期工作。Spring Boot 为 Maven 和 Gradle 提供了特定的集成。如果您使用 Maven,启用 native profile 会触发构建原生镜像所需的基础设施

$ ./mvnw -Pnative package

对于 Gradle,我们的插件对 Native Build Tools 插件的存在作出反应,因此我们需要应用它

plugins {
  ..
  id 'org.graalvm.buildtools.native' version '0.9.14'
}

完成后,这将触发构建原生镜像所需的基础设施

$ ./gradlew nativeCompile

这会为您的本地 OS/CPU 生成原生二进制文件,分别位于 target/build/native/nativeCompile 中。您可以像启动任何其他二进制文件一样启动您的应用。例如,使用 Maven

$ target/demo

构建时优化应用

在 3.0 中,我们的构建插件有一个额外的目标,该目标触发应用的前期(ahead-of-time)处理。在该阶段,会检查应用,并评估和记录我们通常在运行时做出的某些决策。

虽然 Spring Boot 附带了大量的自动配置,但在至少有一个类路径条件匹配之前,这些自动配置是“休眠”的。构建原生镜像时,此类评估必须在镜像构建之前发生,否则所有组合都将包含在其中。

我们还需要检测 GraalVM 无法推断的用例,例如代理、反射和序列化的使用以及资源加载。检测结果形成了所谓的“可达性元数据”。整个 Spring 产品组合已更新,以检测此类用例并自动生成相关的元数据。

我们决定生成包含 Javadoc 和易于浏览结构的源代码。这使得构建时生成的代码可以被检查,并在必要时轻松调试。这也意味着我们只将常规编译的 Java 作为结果提供给 native-image

可达性元数据仓库

虽然对于原生兼容性的首选选项是每个库提供所需的额外可达性元数据提示,但这并非总是可能。最近,Oracle Labs 宣布了一个 第三方可达性元数据共享仓库。该仓库开放供贡献,以收集整个 JVM 生态系统的可达性元数据。每个条目都会针对一系列版本进行隔离测试。

如果您喜欢的库没有提供必要的元数据,请考虑为此仓库做出贡献。Spring 团队正在根据我们提供的第三方库集成积极贡献。

测试支持

我们对原生镜像的支持是通过基于其依赖和配置来优化应用,并推断对反射、代理等的需要。这可能会遗漏一些特定于您的应用的方面,例如其对自定义库或框架的使用。为了帮助您解决这个问题,此里程碑版本还提供了一种在原生镜像中运行现有测试的简单方法,从而允许您验证您的应用及其依赖是否按预期工作。

要在原生环境中运行您的测试套件,我们依赖于 Native Build Tools 插件的测试支持。首先,确保您的路径中可以使用 native-image(请参见上文了解设置说明)。

使用 Maven,可以按如下方式调用

$ ./mvnw -PnativeTest test

使用 Gradle,命令如下

$ ./gradlew nativeTest

对于使用 ApplicationContext 的测试,这会应用相同的过程来优化它并推断必要的元数据。

您的应用不工作:现在怎么办?

如果您的应用无法作为原生镜像工作,我们很乐意听取您的意见,并在候选发布版本(计划在 10 月下旬发布)之前改进我们的支持。支持因错误类型而异

  • 在前期优化阶段构建失败,请向 Spring Framework 问题跟踪器报告。
  • 在生成原生镜像期间构建失败可能有多种根本原因。请使用常见的支持渠道,如 Gitter 或 StackOverflow
  • 如果应用构建成功但启动失败,则很可能缺少某些可达性元数据。对其的需求可能来自您自己的代码,或来自第三方库。

Spring Framework 6 附带了一个新的 API,允许您以编程方式记录提示。如果缺少的提示来自您自己的代码,请考虑实现 RuntimeHintsRegistrar。请参阅这个 示例应用了解具体示例。

后续步骤

根据社区反馈,我们将继续改进我们的 AOT 引擎并更新参考指南,以提供有关我们引入的新 API 的更多详细信息。我们计划于今年 11 月进入 GA 阶段。

这对我们来说是一个激动人心的时刻。我们再次感谢所有已经贡献和提供反馈的人,并期待未来更多反馈!

获取 Spring 新闻通讯

订阅 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助力您的快速提升。

了解更多

获取支持

Tanzu Spring 通过一个简单的订阅即可为 OpenJDK™、Spring 和 Apache Tomcat® 提供支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区即将举行的所有活动。

查看全部