全新AOT引擎将Spring Native提升到新的高度

工程 | Sébastien Deleuze | 2021年12月9日 | ...

谨代表团队和所有贡献者,我很高兴地宣布发布Spring Native 0.11,它为Spring Boot 2.6提供原生支持。这个雄心勃勃的版本是Spring团队五个月辛勤工作的成果,他们一直在致力于一个全新的架构,将Spring对使用GraalVM创建原生可执行文件的支持提升到一个新的水平。您现在就可以在start.spring.io上尝试它!

在本视频中了解更多关于Spring Native 0.11的信息,并亲身体验Spring开发者布道者Josh Long带来的全新Spring Tips视频。

新的提前编译(AOT)引擎

最大的变化无疑是引入了新的AOT引擎,它在构建时对您的Spring应用程序进行深度分析,以转换和优化您的应用程序并生成所需的GraalVM原生配置。这些转换由Maven和Gradle Spring AOT插件执行。

spring boot native

深入研究一下,AOT引擎在构建时评估条件,以便生成针对您的应用程序专门设计的优化应用程序上下文和Spring工厂(Spring Boot背后的插件系统)。实际上,这意味着:

  • 运行时需要执行的Spring基础设施更少

  • 运行时需要评估的条件更少

  • 反射更少,因为使用了程序化Bean注册

AOT引擎根据被识别为活动的Bean、Spring编程模型的知识以及Spring Native捆绑的或由您的应用程序本身提供的原生提示,推断运行您的应用程序作为原生可执行文件所需的原生配置。

aot architecture

我们要特别感谢Stéphane Nicoll,他领导了这个新的AOT引擎的设计和实现。

减少内存占用

AOT引擎的一个关键优势是它支持更小的原生可执行文件的内存占用,因为原生配置更准确,需要的反射更少,运行时需要的Spring基础设施更少。

与Spring Native 0.10相比,Spring Native 0.11的内存占用平均减少了**20%**到**26%**!下图显示了一些示例应用程序的数据点。

native rss

更快的启动速度

与0.10相比,Spring Native 0.11的启动速度提高了**16%**到**35%**,因为一些处理过程已从运行时转移到构建时。仍然有改进的空间,因为我们无法在这个次要版本更新中微调Spring Boot和Spring Framework的内部架构。

native startup

改进的兼容性

AOT引擎也更加准确,因为它不尝试分析Spring注解或各种类型以复制Spring在运行时执行的操作。相反,它会创建一个新的进程,在构建时创建和内省应用程序上下文(无需启动它)。这允许使用Spring Framework在运行时执行操作的一个子集,并在Bean定义级别工作,这更加准确。

运行时灵活性

在构建时执行这些优化意味着运行时的灵活性不如常规的Spring Boot自动配置模型。在运行已编译的Spring Boot应用程序时,您仍然可以更改HTTP端口或应用程序的日志级别,但是例如,您不能通过使用配置文件在运行时添加新的Bean。

这就是为什么在JVM上,AOT模式是可选的。如果您需要,可以使用这种优化。在原生环境中(设计上,运行时动态性要低得多),它是强制性的。此外,请记住,目前条件是在构建时评估的。我们可能会在将来使其更灵活,以便它能够适应大多数用例。

扩展点

新引擎提供了一个可插拔和模块化的架构,用户(例如您或Spring项目团队)可以使用它来支持各种新功能。

例如,请参阅BeanFactoryNativeConfigurationProcessor扩展点的此实现,它会提前为使用@RequestScope@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)注解的Bean自动创建类代理。

public class ScopeNativeConfigurationProcessor implements BeanFactoryNativeConfigurationProcessor {

   @Override
   public void process(ConfigurableListableBeanFactory beanFactory, NativeConfigurationRegistry registry) {
       new BeanFactoryProcessor(beanFactory).processBeansWithAnnotation(Scope.class, (beanName, beanType) -> {
           Scope scope = beanFactory.findAnnotationOnBean(beanName, Scope.class);
           if (scope.proxyMode() == ScopedProxyMode.TARGET_CLASS) {
               registry.proxy().add(NativeProxyEntry.ofClass(beanType, ProxyBits.NONE,
                       ScopedObject.class, Serializable.class, AopInfrastructureBean.class));
           }
      });
   }
}

NativeConfiguration扩展点也已改进,可以使用NativeConfigurationRegistry提供API。

public interface NativeConfiguration {
   default boolean isValid(AotOptions aotOptions) { return true; }
   default void computeHints(NativeConfigurationRegistry registry, AotOptions aotOptions) { return; }
}

这些扩展点在META-INF/spring.factories中定义和发现,因此您可以提供您自己的扩展点

AOT测试支持

我们在Spring Native 0.11上的工作中非常重要的一部分是实现AOT代码路径的测试支持,以便将原生测试支持提升到一个全新的水平。其结果是兼容性得到了显著提高,支持的测试类型也多了很多。

结合原生构建工具提供的强大的JUnit 5原生支持,您可以像在JVM上一样运行Spring Boot、Spring Framework或只是普通的JUnit测试。

与Spring无关的是,目前还不支持Mockito,但正在进行工作,使其将来能够工作。

JVM上的AOT

对将在JVM上运行的应用程序执行AOT转换有两个主要好处。

首先,可以轻松地在您的IDE中调试将在JVM上运行的原生代码(主应用程序或测试)。

第二个优点是更高的效率。目前,它可以减少大约4%17%的内存占用。

jvm rss

AOT模式还可以将应用程序启动速度提高3%24%

jvm startup

请注意,到目前为止,我们还没有特别关注JVM效率,因此在后续版本中可能会有改进的机会。

Bellsoft Liberica NIK

Bellsoft Liberica Native Image Kit (NIK) 是一个基于GraalVM 开源仓库和 Liberica JDK 的原生镜像编译器发行版。从 Spring Native 0.11 开始,它被默认用于 Buildpacks 原生支持,这与 JDK 端一致,JDK 端默认使用 Liberica JDK。它也可以通过使用其SDKMAN集成或下载并安装它来在本地安装。

今年早些时候,该团队与 BellSoft 共同宣布,使用 Liberica Native Image Kit 的 VMware 客户可以将其 Spring 应用程序作为原生可执行文件运行,并确信它们得到完全支持。

新的基线

Spring Native 0.11 也使我们有机会基于Spring Boot 2.6提供一个新的基线。

GraalVM 21.3同时支持Java 11和Java 17,并利用条件原生配置和其他相关的改进,以实现更小的内存占用和对JVM生态系统的更好原生支持。由于Java 8版本的GraalVM过于陈旧,难以维护,因此不再提供,但是您仍然可以使用Java 11版本的GraalVM编译大多数Java 8应用程序。Native Build Tools 0.9.8受支持,我们将继续合作对其进行改进。

Spring Boot 3 一流的原生支持

我认为 Spring Native 0.11 达到了为 Spring Boot 提供成熟的原生选项的目标。Spring 团队现在可以专注于下一个主要步骤:作为 Spring Framework 6、Spring Boot 3 和相关产品组合项目的一部分,改进原生支持。

请记住,我们在 Spring Native 上所做的一切都是与其他 Spring 项目紧密合作完成的,但没有进行深入的架构更改。随着 AOT 和原生成为 Spring Boot 3 和 Spring Framework 6 的主要主题,这些功能的质量、可维护性和易用性将达到一个新的水平。AOT 引擎将被改进并直接集成到 Spring Framework 中。其他项目(如 Spring Data 或 Spring Security)将能够为其范围提供原生支持(并对其进行测试),而 Spring Boot 将在其插件和文档中提供开箱即用的 AOT 和原生可执行文件支持。

boot3 aot architecture

我们将加强与 GraalVM 团队和 JVM 生态系统的合作,以便为 Spring 之外的各种库提供原生配置,无论是在这些库中直接提供,还是在 Native Build Tools 级别直接集成的原生配置存储库中提供。

我们计划在2022年5月的Spring Boot 3里程碑3中开始开箱即用地提供 GraalVM 原生支持,利用我们在 Spring Native 开发过程中获得的所有经验。计划于2022年末正式发布。我们有很多令人兴奋的计划,但现在,让我们花时间与为其做出贡献的 Spring 团队和 Spring 社区成员一起庆祝此次发布。干杯!

获取Spring通讯

关注Spring通讯

订阅

领先一步

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

了解更多

获取支持

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

了解更多

即将举行的活动

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

查看全部