快人一步
VMware 提供培训和认证,助您加速进步。
了解更多我代表团队和所有贡献者,很高兴宣布 Spring Native 0.11 版本发布,它为 Spring Boot 2.6 提供了原生支持。这个雄心勃勃的版本是 Spring 团队五个月辛勤工作的结果,他们一直在开发一个全新的架构,以将 Spring 对使用 GraalVM 创建原生可执行文件的支持提升到新的水平。您已经可以在 start.spring.io 上试用它了!
在 Spring Developer Advocate Josh Long 的这部新 Spring Tips 视频中,了解更多关于 Spring Native 0.11 的信息并观看实际演示。
毫无疑问,最大的变化是引入了一个新的 AOT 引擎,它在构建时对您的 Spring 应用程序进行深度分析,以转换和优化您的应用程序,并生成所需的 GraalVM 原生配置。这些转换由 Maven 和 Gradle Spring AOT 插件执行。
深入来看,AOT 引擎在构建时评估条件,以便生成一个经过优化的应用程序上下文和 Spring factories(Spring Boot 背后的插件系统),这些都专门为您的应用程序量身定制。实际上,这意味着
运行时需要执行的 Spring 基础设施更少
运行时需要评估的条件更少
更少的反射,因为使用了编程式 Bean 注册
AOT 引擎根据标识为活动的 Bean、Spring 编程模型的知识以及 Spring Native 捆绑的或您的应用程序自身提供的原生提示,推断出将您的应用程序作为原生可执行文件运行所需的原生配置。
我们要特别感谢 Stéphane Nicoll,他领导了这款新 AOT 引擎的设计和实现。
AOT 引擎的一个关键优势在于它支持更小的原生可执行文件内存占用,因为原生配置更加精确,所需的反射更少,并且运行时所需的 Spring 基础设施更少。
相比 Spring Native 0.10,Spring Native 0.11 平均可减少 20% 到 26% 的内存占用!下图展示了一些示例应用程序的数据点
相比 0.10 版本,Spring Native 0.11 的启动时间快了 16% 到 35%,因为一些处理已从运行时移至构建时。由于在此次小版本更新中未能对 Spring Boot 和 Spring Framework 的内部架构进行精细调整,因此仍有改进空间。
AOT 引擎也更加精确,因为它不会试图分析 Spring 注解或各种类型来复制 Spring 在运行时所做的工作。相反,它会启动一个新的进程,在构建时创建并内省(introspect)应用程序上下文(而不启动它)。这允许使用 Spring Framework 在运行时执行的一部分功能,并在 Bean 定义层面工作,这要精确得多。
在构建时执行这些优化意味着运行时灵活性不如常规的 Spring Boot 自动配置模型。您在运行已经编译好的 Spring Boot 应用程序时,仍然可以更改 HTTP 端口或日志级别,但例如,您无法在运行时通过使用 Profile 来添加新的 Bean。
这就是为什么在 JVM 上,AOT 模式是可选的。如果它符合您的需求,这是一个可以使用的优化。在原生应用程序中(其设计决定了运行时动态性较低),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
中定义并被发现,因此您可以提供自己的实现。
我们在 Spring Native 0.11 上的大部分工作都集中在实现对 AOT 代码路径的测试支持,以便将原生测试支持提升到全新的水平。结果是兼容性得到了显著提升,支持更多种类的测试。
结合 Native Build Tools 提供的出色的 JUnit 5 原生支持,您可以像在 JVM 上一样运行您的 Spring Boot、Spring Framework 或纯 JUnit 测试。
与 Spring 无关,Mockito 尚未支持,但正在进行相关工作,使其将来成为可能。
在 JVM 上运行的应用程序进行 AOT 转换有两个主要好处。
第一个好处是,例如,您可以在 IDE 中轻松调试将在 JVM 上原生运行的代码(主应用程序或测试)。
第二个优势是效率更高。目前,它可以提供大约 4% 到 17% 更小的内存占用。
AOT 模式还能将应用程序启动速度加快 3% 到 24%。
请注意,到目前为止,我们还没有特别关注 JVM 的效率,因此在未来的版本中很可能有改进的机会。
Bellsoft Liberica Native Image Kit (NIK) 是一个基于 GraalVM 开源仓库和 Liberica JDK 的原生镜像编译器发行版。从 Spring Native 0.11 开始,它默认用于 Buildpacks 的原生支持,这与默认使用 Liberica JDK 的 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 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 和原生可执行文件支持。
我们与 GraalVM 团队和 JVM 生态系统的合作将增加,以便为 Spring 之外的各种库提供原生配置,这些配置可以直接放在这些库中,也可以放在直接集成到 Native Build Tools 层面的原生配置仓库中。
我们计划在 2022 年 5 月发布的 Spring Boot 3 milestone 3 中开始提供开箱即用的 GraalVM 原生支持,充分利用我们在 Spring Native 工作中学到的所有经验。通用版本预计于 2022 年底发布。我们有许多令人兴奋的计划,但现在,让我们与 Spring 团队成员和做出贡献的 Spring 社区成员一起庆祝本次发布。干杯!