Spring Framework 6.0.0-M3 中的初始 AOT 支持

工程 | Stéphane Nicoll | 2022年3月22日 | ...

了解Spring Native实验项目的各位都知道,自2019年以来,Spring团队一直在致力于为Spring应用程序提供原生镜像支持。在2021年3月发布首个 Beta 版本之后,我们在2021年12月发布了Spring Native工作的扩展修订版

我们还在去年SpringOne 大会上宣布,我们打算在2022年期间将这项工作推广到Spring Framework 6.0 正式版。在发布我们的第三个里程碑版本之后,这篇博客文章将引导您了解已经包含的内容以及接下来的内容。

提前处理 (Ahead-Of-Time Processing)

提前处理应用程序上下文为优化打开了更多可能性。根据上下文,我们可以减少需要交付的基础设施数量,预计算组件上声明的某些特性从而加快启动时间,并识别在受限环境中可能存在问题的地方并为其提供替代方案。

Spring Framework 6.0.0-M3 基于 Spring Native 提供了这些功能的第一批功能,但经过了扩展审查并集成到核心容器中。与其将其作为附加模块的新功能,不如将其深度集成到现有模块的核心。目前它包括:

  • 一个针对给定类路径处理 ApplicationContext 并贡献代码以提供其优化版本的引擎。
  • 一个贡献运行时提示的新 API:集成者通常在需要在其自身组件中使用反射时,或者例如需要访问类路径上的某些资源时使用此 API。这些提示与 GraalVM 兼容,我们提供了生成足够配置文件的基础设施。

在构建时优化应用程序

当典型的 Spring 应用程序运行时,应用程序上下文会调用许多后处理器来准备 bean 工厂:配置类解析、类路径扫描以及最终可能触发自动配置解析的其他处理器。一旦这些运行完成,在大多数情况下,它们在运行时就不再需要了。

在定义明确的环境(类路径等)下,这可以在构建时完全完成,以便只有当前环境的相关 bean 定义才会贡献到 bean 工厂。在构建时运行的后处理器将被丢弃,并替换为它们贡献的代码。

有很多方法可以“提前”贡献代码,从注解处理到字节码生成。我们选择让我们的新引擎生成 Java 源代码并在构建过程中将其贡献到应用程序中。我们相信这在开发人员体验和优化机会之间取得了正确的平衡。

这不仅应该以熟悉和透明的方式启用原生用例,而且我们也相信这将在将来为普通 JVM 应用程序带来好处。例如,AOT 引擎完全独立于原生,因此您可以验证应用程序的优化版本是否可以在 JVM 上运行。

运行时提示

与 JVM 不同,运行原生镜像需要针对某些场景进行额外配置。例如,如果您的代码通过反射调用方法,则需要提及这一点,以便在原生镜像中交付必要的基础设施。或者,如果您需要读取类的元数据(就像核心容器在启动时经常做的那样),则需要交付类的字节码,这可能会导致更大的镜像。

AOT 引擎将自动推断启动核心容器所需的所有提示。将来,我们希望这些提示能够减少,以支持 GraalVM 本身的改进,或者使它们不再需要的优化更改。

测试注意事项

生成代码需要良好的测试方案。贡献可能无法编译的代码,或者可以编译但不会产生预期结果的代码太容易了。我们一直在努力开发新的测试实用程序来帮助我们解决这个问题,您可以在当前私有的spring-core-test模块中找到它们。

简而言之,此基础设施使我们能够编译代码(使用允许我们在内存中提供源代码的抽象)并运行断言,其中生成的代码可以轻松检索。

让我们假设我们已经为许多 Java 类生成了代码,并且我们的入口点是MyObject

TestCompiler.forSystem().withSources(sourceFiles)
        .compile(compiled -> {
    MyObject instance = compiled.getInstance(MyObject.class);
    // invoking + assertions
});

在我们的例子中,AOT 引擎生成一个实现ApplicationContextInitializer接口的入口点。此类基础设施使我们能够执行以下操作:

  • 配置应用程序上下文以练习特定功能
  • 在上下文中调用 AOT 引擎
  • 使用TestCompiler编译我们生成的源代码
  • 创建一个新的应用程序上下文并将生成的代码应用于查看该功能是否按预期工作

上面关于生成的代码的描述同样适用于提示。我们正在开发其他测试实用程序来验证您贡献的提示是否与运行时行为匹配。但这在本次里程碑中没有实现,请订阅#27981以了解更多详细信息

接下来是什么?

我们将在下一个里程碑中继续基于 Spring Native 的经验构建核心基础设施。以前在 Spring Native 中使用的特定 Spring 项目的自定义将迁移到项目本身,或者通过适应引擎开箱即用的支持而变得无关紧要。

Spring Framework 6.0 只是一个起点:我们打算在未来几年继续构建这些基础,这也会对 JVM 用户产生积极影响。敬请期待!

获取 Spring 新闻通讯

随时关注 Spring 新闻通讯

订阅

领先一步

VMware 提供培训和认证,以加快您的进度。

了解更多

获得支持

Tanzu Spring在一个简单的订阅中提供对OpenJDK™、Spring和Apache Tomcat®的支持和二进制文件。

了解更多

即将举行的活动

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

查看全部