在2022年5月26-27日的Spring I/O大会上,Spring框架的主要作者Juergen Hoeller对Spring Framework 6.0版本进行了总体介绍,本文为演讲的PPT的翻译。
1、发布日期
Spring Framework 6.0正式版发布日期预计是2022年11月份,此时JDK的版本应该是19。
早期尝鲜者,现在就可以去尝试了,现在最新的版本是Spring Framework 6.0-M4。
2、主要特性
- JDK 17+
- Jakarta EE 9+(Jakarta命名空间)
- 可观查性(Micrometer)
- AOT(Ahead-Of-TIme)
- Java平台模块系统
- 虚拟线程
3、AOT
通过编译时预处理获得更精简的部署单元
- Spring 5:使用spring-context-indexer进行预计算类路径扫描
- Spring 6:编译时自查整个应用的配置
- 将声明式的Bean定义变成编程式的来源
为反射、资源、序列化和代理提供运行时提示(Runtime hints)
灵活且可定制,适用于众多Spring 启动场景
使用AOT还是不使用AOT
- 减少生产中的启动时间
- 减少生产中的内存占用
- 使用“AOT”设置进行测试以保持与生产环境保持一致
GraalVM 原生可执行文件的前提条件
AOT 是一种权衡取舍:额外的构建设置和较低的运行时灵活性
为优化的JVM部署
- AOT预处理在很多场景下都有用
- 重要的是:优化现代的虚拟机部署
- 以稍长的构建时间换取改进的启动时间
- 可与其他虚拟机启动改进相结合
为HotSpot JVM准备更短的启动时间
为GraalVM原生可执行文件
- GraalVM 是原生可执行文件的事实标准
- 强大的“封闭世界假定”(当前不是已知的事物都为假的假定),无运行时适应
- AOT处理的应用作为输入->原生可执行文件作为输出
为原生代码生成需花费很长的编译时间
具有强大优势和局限性的不同部署模式
为OpenJDK静态镜像(Project Leyden)
- 展望未来,OpenJDK的目标是引入静态镜像
- 为特定应用定制基于特定HotSpot运行时镜像
- 渐进式方法:较弱的约束->更强的运行时灵活性
严格的“封闭世界限制”作为终极目标
Spring的AOT策略和Leyden的虚拟机策略一致
4、Java平台模块系统
支持应用作为显式的模块构建
- 当前:Spring 5的jar声明为自动模块
- Spring应用选择模块路径而不是类路径
- 应用自带“module-info.java”声明
框架模块的传递性解析
- 当前:定义明确的模块名称,但没有依赖声明
- Spring 6计划:带有module-info的jar,需要传递模块
- 在应用级别模块声明中方便使用
框架模块 vs jlink镜像
- jlink命令行工具用来编译自定义运行时镜像
- 需要模块声明module-info
- 自动模块仍然可以以jar包的形式部署在镜像上
Spring 6:可能在jlink镜像中纳入框架模块
建议:保持将框架模块部署为jar
重新设计以最小化jlink镜像的占用
- Spring 5 需要相当大的带有 JDK 模块的 jink 基础镜像
- 主要是由于包含 java.beans 的 java.desktop 模块
- 可能重新设计JavaBean的自查功能
避免来自java.beans包的API类型和实现
还没有决定:为了有限的利益而影响兼容性?
类路径扫描 vs 模块路径扫描
- Spring 5 即使在模块里也是使用传统的类路径扫描
- 模块内容的不完整视图。如:带有补丁的模块
- Spring 6:通过JDK的ModuleReader API来进行模块路径扫描
与常见构建方法的兼容。如:Maven Surefire
在模块环境中自动适配
5、虚拟线程
“Project Loom”将在JDK 19中进入预览
- JDK 19最终包括Project Loom作为常规预览版
- 虚拟线程是JVM里的轻量级线程模型
- 命令式编程的不同规模的可伸缩性
实现为 java.lang.Thread 的虚拟变体
在I/O操作中不阻塞操作系统线程
与“Project Loom”兼容的基础设施
- JDK文件访问和网络库隐式释放载体线程
- 同步块中的 I/O 操作不会释放载体线程
- 重新审视HTTP引擎和JDBC驱动的实现
虚拟线程并不意味着被池化,而是为每个任务新创建的线程
我们期望在生态系统中为“Project Loom”兼容性做出努力
针对web应用
- 早期的Loom实验已经使用web容器进行工作
- Servlet的回调方法基于InputStream/OutputStream
- Tomcat/Jetty执行器设置用来分发到请求处理
希望在应用程序代码库中几乎没有任何必要的变化
数据库驱动的 Web 应用程序有望获得显著的可伸缩性的优势
针对消息/计划任务
Spring管理的任务执行器/计划器都有虚拟线程选项
- 如:JMS消息监听容器
- 如:@Schedule处理方法
很多监听器/处理程序触发I/O操作
注意:对于纯粹的CPU绑定的处理程序来说,完全没有预期的好处。
6、修订的 Web 应用程序基础设施
几个长期计划的6.0特性
- 基于@HttpExchange服务接口的Http接口客户端
- 支持RFC 7807问题细节
- 统一的HTTP状态码处理
- 修改了WebFlux上传文件处理部分
- JDK HttpClient 与 WebClient 的集成