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 一起进入通用可用阶段!

原生镜像可以为 Java 应用程序提供近乎即时的启动时间和更低的内存消耗。最近发布的 Spring Boot 3.0.0-M5 版本是我们首次就原生支持征求更广泛的社区反馈。如果您需要了解基础知识,请参考三月下旬发布的 提前编译 (Ahead Of Time) 基础知识博客文章。您还可以了解 如何为 Spring Boot 3.0 准备您的应用程序

自三月以来,已经发生了很多事情!我们提高了与更多用例和库的兼容性,并在此过程中修复和改进了我们的原生支持。这篇博客文章详细介绍了您开始所需了解的内容。

构建您的第一个原生镜像

开始最简单的方法是使用 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,启用原生配置会触发构建原生镜像所需的必要基础结构

$ ./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 版本中,我们的构建插件增加了一个额外的目标,用于触发应用程序的提前编译处理。在此阶段,应用程序将被检查,并且一些我们通常在运行时做出的决策将被评估和记录。

虽然 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 的测试,这会应用相同的优化过程并推断出必要的可达性元数据。

您的应用程序不起作用:现在怎么办?

如果您的应用程序无法以原生镜像形式运行,我们很乐意听到您的反馈,并在计划于十月下旬发布的发布候选版本之前改进我们的支持。支持因错误而异

  • 在提前编译优化阶段出现构建失败,请报告给 Spring Framework 问题跟踪器
  • 在生成原生镜像期间出现的构建失败可能有多种根本原因。请使用 Gitter 或 StackOverflow 等常规支持渠道
  • 如果应用程序成功构建但启动失败,则很可能是缺少某些可达性元数据。这可能源于您自己的代码,也可能源于第三方库。

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

下一步

基于社区反馈,我们将继续改进我们的 AOT 引擎,并更新参考指南,以提供有关我们引入的新 API 的更多详细信息。我们计划于今年十一月正式发布。

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

获取 Spring 新闻通讯

通过 Spring 新闻通讯保持联系

订阅

领先一步

VMware 提供培训和认证,助您加速进步。

了解更多

获得支持

Tanzu Spring 提供 OpenJDK™、Spring 和 Apache Tomcat® 的支持和二进制文件,只需一份简单的订阅。

了解更多

即将举行的活动

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

查看所有