写点什么

对话 Spring 大神:Spring 生态系统的新时代来了!

作者:Josh Long, Karsten Silz

  • 2022-12-05
    北京
  • 本文字数:7289 字

    阅读完需:约 24 分钟

对话Spring大神:Spring 生态系统的新时代来了!

VMware 发布了 Spring Framework 6 和 Spring Boot 3。在 Spring Framework 5 发布 5 年之后,这些新版本开启了 Spring 生态系统的新时代。Spring Framework 6 需要 Java 17 和 Jakarta EE 9,并与最近发布的 Jakarta EE 10 兼容。它还通过带有跟踪和指标功能的 Micrometer 内嵌了可观察性。Spring Boot 3 需要 Spring Framework 6,内置支持使用 GraalVM 原生镜像的静态预先编译(AOT)构建原生可执行文件。关于这两个新版本框架的更多细节可以在 InfoQ 的这个报道中找到。

 

InfoQ 就这两个新版本的框架采访了 Java Champion、VMware 的 Spring 开发者布道师Josh Long。VMware 的 Spring Framework 项目负责人Juergen Hoeller也回答了其中一个问题。

 

InfoQ:作为一名 Spring 开发者布道师,你会发表演讲、编写代码、发表文章和书籍,并运营着一个播客。那么你的一天是怎么过的?

 

Josh Long:这很难说!我的工作需要我和各种各样的人交流,面对面或通过网络,所以我永远不知道我会在哪里,也不知道我会专注在什么事情上。不过通常来说,我的目标是推动生态系统的发展。也就是说,我要了解他们的应用场景,并推动他们找到问题的解决方案。如果说这需要我和 Spring 团队交流或贡献代码,我很乐意这么做。如果说需要我发表演讲、录制播客、写一些文章或一本书或制作视频,我也会去做。

 

InfoQ:VMware 从许多来源获得关于 Spring 的反馈:会议、用户组、问题跟踪器、Stack Overflow、Slack、Reddit、Twitter 等等。但满意度高的用户通常不会说什么,而抱怨声最大的人可能反应不了本质的问题。那么,VMware 是如何收集用户反馈和给它们安排优先级的呢?

 

Long:这是一个非常好的问题:所有的东西最终都会落到 GitHub 上。我们特别关注 StackOverflow 标签,并尽最大努力对它们做出响应。但如果在那里发现了 bug,最终会落到 GitHub 上。GitHub 是参与这个项目的一个很好的方式。我们试着让它变得简单,比如为那些想要参与贡献的新人创建标签,让他们从可以接受我们指导的地方开始。当然,GitHub 不是一个进行问答的好地方——所以我们使用 Stackoverflow。我们非常依赖 GitHub,以至于即使在团队内部,我们也会向自己的项目发送拉取请求并使用这个工作流。

 

InfoQ:Spring 下有很多项目。VMware 必须让 Spring 用户了解所有相关的东西。VMware 如何知道 Spring 用户不了解哪些东西,从而可以教会他们?

 

Long:简单地说,我们不知道,不过我们可以猜测。我们花了很多精力开发新的、新颖的、最新的和最好的项目,也在不断更新基础的东西。你不会相信我为一些项目重做了多少次“开始的第一步”之类的东西。我们也非常清楚,登陆我们门户网站的人可能是长期用户,但通过其他方式找到 Spring 的人对 Spring 可能了解甚微。所以我们要不断推出“开始的第一步”的介绍性内容。有时候“开始的第一步”变化得足够多,以至于最基础的东西也变得很新颖。

 

InfoQ:Java 遗留应用程序通常使用较老版本的 Java 和框架。微服务架构让开发人员可以以较低的风险引入新的技术栈。你是否认为这是 Java 展示新特性和新版本的好机会?或者这更像是一种对 Java 的威胁,因为开发人员可以尝试 Java 的竞争对手,如.NET、Go、JavaScript 或 Python?

 

Long:威胁?恰恰相反——如果在其他编程语言看来,Java 表现得很差,那么最好将其暴露出来,这样可以推动 Java 向前发展。而且,老实说,Java 不可能在所有方面都是最好的。微服务意味着我们可以在有意义的场景中使用 Spring 和 Java,不会有 Java 和 Spring 不能提供最好的解决方案时就会陷入困境的感觉。不要问我是什么样的场景,因为我真的不知道……

 

InfoQ:Spring 5 增加了对 Kotlin 的显式支持。你估计现在有多少百分比的 Spring 开发使用的是 Kotlin?

 

Long:我不知道,但 Kotlin 是 Spring Initializer 上被使用第二多的语言。

 

InfoQ:Scala 从来没有获得 Spring 这种显式的支持。你认为这是为什么?

 

Long:有的!早在2012年,我们就有一个叫作 Spring Scala 的项目。我们真的希望它能成功。在我们发布 Spring Scala 之前,我们甚至有一个 Scala 的 Spring Integration DSL。我们尝试过了,但似乎没有一个社区希望它能成功。这是一个遗憾。如今,随着反应式和函数式编程的日益崛起,我觉得 Java 和 Scala 社区之间的共性变得比以往任何时候都要大。

 

InfoQ:Spring 5 也加入了反应式应用程序。现在你是反应式应用程序的支持者,甚至还为此写了一本书。是什么让反应式应用程序对你如此有这么大的吸引力?

 

Long:我喜欢反应式编程。它为我们带来了三个显著的好处:

 

1. 一种用来表达系统状态转移的 DSL——通过回压、超时、重试等机制来健壮地解决系统的脆弱性问题。这种简洁的 DSL 简化了构建系统的过程,你最终得到的是一个为所有场景提供的抽象。

2. 一种用来编写多线程并发代码的 DSL——没有那么多困扰并发代码的线程和状态管理逻辑。

3. 能够优雅地编写让运行时更好地伸缩线程(即每秒处理更多请求)的代码。

 

InfoQ:反应式开发最适合解决哪些问题或最适合用于构建哪种应用程序?

 

Long:如果反应式抽象适合你的领域,并且你想学习一些新东西,那么反应式编程就可以用于所有的工作负载。编写更可伸缩、更安全(更健壮)和更一致的代码有什么不好的呢?

 

InfoQ:哪些场景不适合使用反应式开发?

 

Long:反应式开发要求代码的编写范式做出一些改变。它不像 Loom 项目,一个开关就可以让你获得可伸缩性方面的一些好处。如果你对学习这种新范式不感兴趣,也不需要反应式编程所能带来的好处,那么它对你来说就没有任何意义。

 

InfoQ:人们对反应式开发常见的抱怨是认知负荷的增加和调试难度的增加。他们抱怨的这些问题在 Spring Framework 6 和 Spring Boot 3 中也会有吗?

 

Long:我不知道我们是否在 Spring Boot 3 中直接解决了这些问题。不过,通常的机制仍然有效!用户可以在反应式管道的各个部分设置断点。他们可以使用 Reactor Tools 从管道中的所有线程捕获堆栈跟踪信息。他们可以使用.log()和.tap()操作符来获取流经管道的数据的信息,等等。Spring Boot 3 有一个显著的改进——Spring 现在支持通过 Micrometer Metrics 和 Micrometer Tracing 捕获指标和跟踪信息。Reactor 甚至提供了对反应式管道中 Micrometer Observation 抽象的支持。

 

InfoQ:工具支持(例如 IDE 和构建工具)对于框架的成功来说有多重要?至少,有经验的用户通常会绕过向导和实用工具,直接修改配置文件和代码。

 

Long:这个问题很有意思。我已经非常努力地证明,工具对于 Spring Boot 开发人员的体验来说并不是非常重要的。事实上,自从 Spring Boot 发布以来,已经可以支持使用任意的 Java IDE 开发新的应用程序。你不需要 IntelliJ IDEA 终极版、对 Spring XML 名称空间的支持,甚至不需要 Eclipse 中的 Java EE 和 WTP 支持来 Spring Boot。如果你的工具支持 public static void main、Apache Maven 或 Gradle,以及所需的 Java 版本,就万事大吉了!

 

Spring Boot 可能在某些地方会从工具中获得好处,比如 application.properties 和 application.yaml。但即使在这里,你也不一定需要工具——Spring Boot 的 Spring Boot Actuator 模块可以为你提供这些文件中定义的所有属性。

 

也就是说,即使你需要亲自编辑所有的东西,你也不会感到麻烦。好的工具会给人一种整个按键都摆在你前面的感觉。谁不喜欢这样呢?为了达到这个目的,我们做了很多工作,尽可能提升 Eclipse 和 VS Code(以及扩展到大多数支持 Eclipse Java Language Server 的工具)的开发者体验。

 

我认为,好的工具对于迁移已有代码来说会更加重要。新的 Jakarta EE API 就是一个很好的例子。Jakarta EE 取代了 Java EE——javax.*下所有的类型都迁移到 jakarta.*下。Eclipse 基金会的工作人员已经付出了巨大的努力,让熟悉这些新类型的过程变得尽可能简单,但仍有很多工作需要完成。我想,你所选择的 IDE 也将使这些变得更容易些。

 

InfoQ:自 2010 年以来,这是第一次 Spring Framework 的更新不是在上一次重大发布一年之后,而是两年之后(5.3 版本在 2020 年发布)。因此,Spring Framework 6 似乎有两年的开发时间而不是一年。是什么导致花了这么长时间?

 

Long:我甚至没有注意到这个!老实说,我感觉 SpringFramework 6 已经开发了两年多了。这个版本令人感到难以置信的忙乱!迁移到 Java17 很容易,但迁移到 JakartaEE 对我们来说是一个挑战。首先,我们必须清理所有受支持的 Spring Boot 库中的依赖项。然后,我们一个接一个地处理所有的库,直到一切都变为绿色。这是一项艰苦而缓慢的工作,我很高兴已经完成了。但是,这些工作对于使用 Spring Boot 的开发人员来说可能是微不足道的。

 

我们也做了大量有关可观测性的工作,要点是 Micrometer 现在支持跟踪,并且跟踪和指标都有一个统一的抽象,即 Observation。现在我们来了解一些背景故事。在 Spring Boot 2.x 中,我们引入了 Micrometer 来捕获指标并将其保存到各种时间序列数据库中,如 Netflix Atlas、Prometheus 等。Spring Framework 依赖 Micrometer,Spring Boot 依赖 Spring Framework,Spring Cloud 依赖 Spring Boot,支持分布式跟踪的 Spring Cloud Sleuth 依赖 Spring Cloud。因此,指标位于抽象栈的最底层,分布式跟踪位于最顶层。

 

这样的抽象栈在很大程度上是没有问题的,但这意味着我们有两种不同的指标和跟踪抽象。这也意味着,如果不引入循环依赖关系,Spring Framework 和 Spring Boot 就不能支持分布式跟踪。Spring Boot 3 中的变化——Spring Framework 依赖 Micrometer,Micrometer 通过一个简单、统一的抽象支持跟踪和指标。

 

最后,使用 GraalVM Native Image 进行提前(AOT)编译的工作在 Spring Framework 6(2022 年 11 月 15 日发布)中正式落地。从 2019 年起,这项工作就已经在以某种形式进行中。最先是一个叫作 Spring Native 的实验性研究项目,我们在这个项目中验证了 Spring Boot 2.x 和 Spring Framework 5.x 的各项功能。这些工作成果已包含在 Spring Framework 6 和 Spring Boot 3 中。

 

InfoQ:正如去年宣布的那样,Spring Framework 6.0 和 6.1 的免费支持时间将更短。与 Spring 5.2 的 27 个月相比,两者都下降了 20%(降至 21.5 个月)。相比之下,Spring Boot 3.0 的免费支持期限仍然为一年。这是为什么?

 

Long:我们在 2021 年底对计算方式进行了标准化。我们一直为开源版本提供 12 个月的免费支持。每个项目都可以根据发布周期和社区需求进行扩展,但所有项目至少需要 12 个月的开源支持和额外的 12 个月商业支持。对于我们来说,在主要版本中进一步扩展对最后一个次要版本的支持是正常的(就像我们在 SpringFramework5.3.x 中所做的那样)。

 

需要注意的是,支持时间的标准化发生在 2021 年底。自那时以来,我们没有发布过任何主要或次要的 Spring Framework 版本。Spring Framework 6 将是新标准下的第一个。

 

Juergen Hoeller:Spring Framework 6.0 和 6.1 的商业支持时间也更短。我们没有为了商业支持而缩短了开源版本的支持时间。更确切地说,所有的时间都变短了——人们希望更快地升级到最新的 6.x 版本,就像他们近来更快地升级 JDK 一样。从这方面来说,Spring Framework 5.x 仍然紧密配合 JDK8 的使用风格——“你可以停留在你的 JDK 级别和 JavaEE 级别上”。Spring Framework 6.x 旨在尽可能紧跟 JDK 17+和 Jakarta EE 9+(两者都比以前更频繁地发布),并相应地调整发布理念。

 

InfoQ:Spring Boot 3 支持 GraalVM Native Image 的 AOT 编译器。这样可以获得启动速度更快、使用更少内存、容器镜像更小且更安全的原生 Java 应用程序。这在云计算的哪些领域会让 Java 与 Go 等竞争对手处于更平等的地位?

 

Long:我不知道我是否应该将 Java 与 Go 放在一起讨论。无论 Go 表现得怎么样,Java 都不是最节省内存的编程语言。这导致 Java 错过了一些机会,如物联网和无服务器。使用 GraalVM Native Image 进行 AOT 编译可以保持 Java 引以为傲的可伸缩性和生产力。

 

InfoQ:原生 Java 在云计算的哪些领域不会起到很大作用?

 

Long:我不知道。我感觉 GraalVM Native Image 可能是 JRE 的替代品。事实上,GraalVM 也打开了新的大门。开发人员现在可以使用 Spring Boot 编写自定义 Kubernetes 控制器。你也可以编写特定于操作系统的客户端二进制文件,如 CLI(hello,Spring Shell!)。

 

InfoQ:原生 Java 的缺点是构建管道更慢、更复杂、工具支持更少、可观察性降低。构建管道的缺点似乎不可避免——AOT 编译需要更长的时间,不同的操作系统需要不同的可执行文件。但是,你认为从中期来看,与动态 Java 相比,原生 Java 的工具支持和可观察性会是怎样的?

 

Long:IntelliJ 已经为调试 GraalVM 原生镜像提供了极好的支持。我不认为大多数人会为失去 Java 引以为傲的可移植性而感到悲哀。毕竟,大多数应用程序都在 Linux 主机上的 Linux 操作系统上的 Linux 容器中运行。有一个很棒的 GitHub Action,你可以用它来进行交叉编译,构建过程可以在多个操作系统上运行,并生成特定于这些操作系统的可执行文件。你可以使用 Buildpacks(Spring Boot 可与之集成,例如:mvn -Pnative spring-boot:build-image)等工具在 macOS 或 Windows 主机上构建和运行容器镜像。GraalVM 的可观测性支持受到了一些影响,因为 Java 代理不能很好地在原生可执行文件中运行。但是,前面提到的 Micrometer 支持可以避开许多限制,并产生更详尽的结果。

 

InfoQ:说到可观测性,这是 Spring 6 的另一个主要功能。它包含了日志记录、指标和跟踪,并是基于 Micrometer 的。Java 已经有许多可观测性选项,为什么要在 Spring 中再加入一个?而且为什么是现在呢?

 

Long:Java 并没有像 Micrometer 那样做了那么多的事情。我们并不是加入了另一个——我们是在增强一个现有的。Micrometer 已成为事实上的标准。许多其他的库已经将其集成到表面指标中:

  • RabbitMQ Java 客户端

  • Vert.x?

  • Hibernate

  • HikariCP

  • Apache Camel

  • Reactor

  • RSocket

  • R2DBC

  • DS-Proxy

  • OpenFeign

  • Dubbo

  • Skywalking

  • Resilience4J(进行中)

  • Neo4J

 

InfoQ:除了直接读取数据文件之外,该如何查看和分析 Spring 6 和 Spring Boot 3 的可观测性数据?

 

Long:Micrometer 提供了一系列与 Graphite、Prometheus、Netflix Atlas、InfluxDB、Datadog 等指标工具集成的能力。它可以与 OpenZipkin 等分布式跟踪工具一起使用。它还与 OpenTelemetry(“OTel”)集成,因此你可以与 OTel 服务通信。

 

InfoQ:Spring Boot 3 在发布时并不会为所有的项目和库提供全面的原生Java和可观测性支持。那么我如何知道我的 Spring Boot 3 应用程序是否可以支持原生 Java 并提供完整的可观察性数据?

 

Long:这只是一个更长、更大的旅程的开始。与 GraalVM Native Image 配合的东西几乎每天都在增加。虽然没有明确的清单,但你应该知道,所有主要的 Spring 项目都在提供支持。这是我们的首要任务。可以看一下我们的Spring AOT冒烟测试,看看哪些核心项目已经经过了验证。

 

InfoQ:Java 即将推出的哪项功能最令你感到兴奋?

 

Long:我对即将到来的三个项目感到非常兴奋:Loom 项目、Leyden 项目和 Panama 项目。Loom 项目为 JVM 带来了轻量级绿色线程,并承诺提升可伸缩性。Leyden项目似乎将为应用程序开发人员提供更多的参数来约束和优化他们的 JVM 应用程序。其中一个更引人注目的限制似乎是 GraalVM 原生镜像。Panama 项目希望最终能让对外函数的访问像 Python、Ruby、PHP、.NET 等语言一样轻松。这三个方面的努力将推动 Java 进入新的领域。

 

InfoQ:如果你能对 Java 做出一个改变,你希望是什么?

 

Long:结构化的 lambda!我想要真正的 lambda。目前,lambda 差不多就是一种单一抽象方法接口的语法糖,所有的 lambda 都必须遵循单一抽象方法(SAM)接口,如 java.util.function.Function<I,O>。这在 Java 加入我喜欢的 var 关键字之前都还好,但现在从美学上看它有点令人感到不快,因为需要告诉编译器给定的 lambda 遵循的是哪个接口。

 

下面是 Kotlin 的一些代码:


val name = "Karen" // 一个常规的String类型变量
val myLambda: (String) -> Int = { name -> name.length } // 一个以字符串为参数并返回整数的lambda
复制代码

 

下面是 Java 的等效代码:


var name = "Karen";
var myLambda = new Function<String, Integer>() {
  @Override
  public Integer apply(String s) {
    return s.length();
  }
};
复制代码


有几种方法可以解决这个问题:

 

var name = "Karen";
Function<String, Integer> myLambda = s -> s.length(); 
复制代码

 

这就是我所说的美学上令人感到不快:要么不能两行都以 var 开头,要么放弃 lambda 的简洁性。

 

这个问题可能会得到解决吗?可能不会。这是一个严重的问题吗?当然不是。总的来说,Java 是一种奇妙的语言。大多数语言都应该很幸运,因为它们也已经到了 Java 的年纪,但没有像它那样奇怪的语法!

 

InfoQ:你希望 Spring 或 Spring Boot 做出一个什么样的改变?

 

Long:这很难说!我希望我们能够恢复并更新 Spring Rich(一个早已失效的框架),用于构建桌面 Swing 驱动的客户端应用程序。目前 Griffon 是唯一能解决这个问题的框架。很遗憾,因为 Spring 本可以在这面做得很棒,特别是现在它已经深度集成了 GraalVM Native Image 支持。当然,这可能也只是一个利基的应用场景。

 

嘉宾简介:

 

Josh Long(推特账号 @starbuxman)是 2010 年以来的第一位 Spring 开发者布道师。Josh 是 Java Champion,著有 6 本书(包括 O’Reilly 的《云原生 Java:使用 Spring Boot、Spring Cloud 和 Cloud Foundry 设计弹性系统》和《Reactive Spring》),录制过众多很受欢迎的培训视频(包括与 Spring Boot 联合创始人 Phil Webb 合作的《使用 Spring Boot 构建微服务》),他还是一名开源贡献者(Spring Boot、Spring Integration、Spring Cloud、Activiti 和 Vaadin 等)、一位播客和 YouTube 博主。

 

Karsten Silz 在欧洲和美国做了 23 年的全栈 Java 开发者(Spring Boot、Angular、Flutter)。2004 年,他在美国联合创办了一家软件产品初创公司。Karsten 领导了 13 年的产品开发,并在公司成功销售后离开。自 2003 年以来,他一直担任承包商。2020 年,他作为首席技术官在英国联合创办了 SaaS 初创企业“Your Home in Good Hands”。

 

原文链接

https://www.infoq.com/articles/josh-long-spring-6/


相关阅读:

Java近期新闻:Spring Framework 6、JCP选举、Valhalla项目、OpenJDK更新

Spring Boot 3将于2022年11月发布,延迟了对Java模块系统的支持

Spring Boot Migrator简介

2022-12-05 18:3811413

评论

发布
暂无评论
发现更多内容

Docker容器中一定要避免的10件事

xcbeyond

Docker 避坑

自从用完Gradle后,有点嫌弃Maven了!速度贼快!

xcbeyond

maven Gradle

如何保证消息不丢失?处理重复消息?消息有序性?消息堆积处理?

Bruce Duan

消息队列 保证消息不丢失 处理重复消息 消息有序性 消息堆积处理

什么?还没有自己的域名?

北漂码农有话说

分布式锁用 Redis 还是 Zookeeper?

xcbeyond

redis zookeeper 分布式锁

week7 总结 性能测试

a晖

第七周总结

Karl

使用HSDB 查看jvm内存

引花眠

架构师训练营作业 (第七周)

默默

MySQL 大表优化方案

Bruce Duan

MySQL优化

Mybatis二级缓存,你确定要用么?

xcbeyond

mybatis 二级缓存 一级缓存

记一次西安thoughtworks的面试经历

xcbeyond

面试 thoughtworks

IDEA 插件: EasyCode 一键生成所需代码

Bruce Duan

idea插件 easycode 生成代码

ARTS 05 - 使用 Ecto.Migration 来做数据库迁移

jerry.mei

学习 算法 ARTS 打卡计划 函数式编程 Elixir

架构师训练营——请简述 CAP 原理

WW

应届生求职面试真的有那么难吗

xcbeyond

面试 应届生

MyBatis几种好用的写法

Bruce Duan

MyBatis标签

技术革新产业变革新动能

CECBC

LeetCode 144. Binary Tree Preorder Traversal

liu_liu

算法 LeetCode

性能测试

满山李子

极客大学架构师训练营

两个指针缩小范围算法,CQRS 命令查询职责分离模式 John 易筋 ARTS 打卡 Week 09

John(易筋)

ARTS 打卡计划

写一个 web 性能压测工具

WW

第六周总结

Karl

架构师训练营 -- 第七周学习总结

花花大脸猫

压测工具

Karl

LeetCode 565. Array Nesting

liu_liu

算法 LeetCode

SpringBoot 使用 jasypt 对配置项进行加密

hungxy

Java springboot jasypt

MinIO 简介和搭建一个对象存储服务

耳东@Erdong

Minio store Object store

ARTS打卡 第8周

引花眠

ARTS 打卡计划

JVM系列之:详解java object对象在heap中的结构

程序那些事

Java JVM GC JOL

Apache BeanUtils和Spring BeanUtils剖析

Bruce Duan

BeanUtils 浅拷贝和深拷贝

对话Spring大神:Spring 生态系统的新时代来了!_云计算_InfoQ精选文章