第六批春季新事
本节重点介绍了Spring Batch 6.0的主要变化。完整的变更列表请参阅发布说明。
Spring Batch6.0包含以下功能和改进:
依赖升级
在这次主要版本中,Spring 依赖升级为以下版本:
-
Spring Framework 7.0
-
春季集成7.0
-
春季数据4.0
-
春季LDAP 4.0
-
春季AMQP 4.0
-
春季卡夫卡 4.0
-
1.16 微米
批处理基础设施配置改进
批处理基础设施配置的新注释和类
在v6之前,@EnableBatchProcessing注释与基于JDBC的基础设施绑定。现在情况已经不同了。引入了两个新的注释来配置底层作业仓库:@EnableJdbcJobRepository和@EnableMongoJobRepository.
从v6开始,@EnableBatchProcessing允许你配置批处理基础设施的通用属性,而存储专属属性则可以通过新的专用注释来指定。
以下是如何使用这些注释的一个示例:
@EnableBatchProcessing(taskExecutorRef = "batchTaskExecutor")
@EnableJdbcJobRepository(dataSourceRef = "batchDataSource", transactionManagerRef = "batchTransactionManager")
class MyJobConfiguration {
@Bean
public Job job(JobRepository jobRepository) {
return new JobBuilder("job", jobRepository)
// job flow omitted
.build();
}
}
同样,基于DefaultBatchConfiguration通过引入两个新的配置类来定义存储特定属性,进行了更新:JdbcDefaultBatchConfiguration和MongoDefaultBatchConfiguration.
这些类可以用来编程配置每个作业仓库以及其他批处理基础设施的属性。
默认是无资源批处理基础设施
这DefaultBatchConfiguration类已更新为默认提供“无资源”批处理基础设施(基于ResourcelessJobRepository实现是在 v5.2 中引入的)。这意味着它不再需要内存数据库(如 H2 或 HSQLDB)来存储作业仓库,而这之前是批处理元数据存储所必需的。
此外,这一变化将提升批处理应用在未使用元数据时的默认性能,因为ResourcelessJobRepository不需要任何数据库连接或事务。
最后,这一变化有助于减少批处理应用的内存占用,因为内存数据库不再需要用于元数据存储。
批处理基础设施配置简化
在v6之前,非平凡的Spring Batch应用配置相当复杂,需要大量资源:JobRepository,JobLauncher,JobExplorer,作业操作员,职位注册,JobRegistrySmartInitializingSingleton诸如此类。这需要大量配置代码,比如需要在两个JobRepository和JobExplorer.
在本版本中,进行了若干更改以简化批处理基础设施配置:
-
这
JobRepository现在JobExplorer因此无需定义单独的接口JobExplorer豆。 -
这
作业操作员现在JobLauncher因此无需定义单独的接口JobLauncher豆。 -
这
职位注册现在是可选的,并且足够智能自动注册作业,因此无需单独定义一个JobRegistrySmartInitializingSingleton豆。 -
事务管理器现在是可选的,并且是默认设置
ResourcelessTransactionManager如果没有提供,则使用。
这减少了典型批处理所需的豆子数量,并简化了配置代码。
块导向处理模型的新实现
这并不是新功能,而是块导向处理模型的新实现。这一新实现最初作为实验性新增于5.1版本,现已在6.0版本中稳定发布。
新的实现方式如下:ChunkOrientedStep类,是替代ChunkOrientedTasklet / 任务步类。
这里有一个定义 的示例ChunkOrientedStep通过使用其构建器:
@Bean
public Step chunkOrientedStep(JobRepository jobRepository, ItemReader<Person> itemReader, ItemWriter<Person> itemWriter) {
int chunkSize = 100;
return new ChunkOrientedStepBuilder<Person, Person>("step", jobRepository, chunkSize)
.reader(itemReader)
.writer(itemWriter)
.build();
}
此外,容错特性也进行了如下调整:
-
重试功能现在基于 Spring Framework 7 引入的重试功能,而非之前的 Spring Retry 库
-
跳过功能已根据新实现进行了轻微调整,该实现现仅完全基于
SkipPolicy接口
这里有一个快速示例,说明如何用新版本使用重试和跳过功能ChunkOrientedStep:
@Bean
public Step faulTolerantChunkOrientedStep(JobRepository jobRepository, ItemReader<Person> itemReader, ItemWriter<Person> itemWriter) {
// retry policy configuration
int maxRetries = 10;
var retrybaleExceptions = Set.of(TransientException.class);
RetryPolicy retryPolicy = RetryPolicy.builder()
.maxRetries(maxRetries)
.includes(retrybaleExceptions)
.build();
// skip policy configuration
int skipLimit = 50;
var skippableExceptions = Set.of(FlatFileParseException.class);
SkipPolicy skipPolicy = new LimitCheckingExceptionHierarchySkipPolicy(skippableExceptions, skipLimit);
// step configuration
int chunkSize = 100;
return new ChunkOrientedStepBuilder<Person, Person>("step", jobRepository, chunkSize)
.reader(itemReader)
.writer(itemWriter)
.faultTolerant()
.retryPolicy(retryPolicy)
.skipPolicy(skipPolicy)
.build();
}
请参阅迁移指南,了解如何从之前的实现迁移到新的实现。
新的并发模型
在此版本之前,基于“并行迭代”概念的并发模型需要在不同层级进行大量状态同步,并且存在限速和背压等多种局限,导致交易语义混乱和性能不佳。
本次发布重新审视了该模型,并基于生产者-消费者模式提出了一种新的简化并发方法。并发的块导向步骤现在使用生产线程和消费者线程之间的有界内部队列。项目一旦准备好处理,立即放入队列,消费者线程则在项目可用时立即从队列中取出。一旦区块准备写入,生产线程暂停直到区块写入完成,然后继续生成项目。
这种新模型更高效、更易理解,并且在并发执行中提供了更好的性能。
新命令行操作员
Spring Batch提供了命令行作业跑者从版本1开始。虽然这款跑道多年来很好地发挥了作用,但在可扩展性和定制方面开始显现出一些局限性。报告了许多问题,如静态初始化、非标准的选项和参数处理方式、缺乏可扩展性等。
此外,所有这些问题使得在 Spring Boot 中无法复用该运行器,导致两个项目中代码重复,以及行为差异(如作业参数与递增器行为差异),这让许多用户感到困惑。
本次发布引入了现代版本命令行作业跑者叫命令行作业操作员允许你从命令行作批处理作业(启动、停止、重启等),并且可以自定义、可扩展,并根据 Spring Batch 6 引入的新变化进行更新。
恢复失败作业执行的能力
在此版本之前,如果作业执行突然失败,无法在没有手动数据库更新的情况下恢复。这容易出错,且不同作业仓库间不一致(因为需要为 JDBC 数据库设置几个 SQL 语句,为 NoSQL 存储需要一些自定义语句)。
本版本引入了一种名为恢复在作业操作员界面允许你在所有作业仓库中一致恢复失败的作业执行。
能够阻止各种步骤
从v5.2开始,只能通过外部停止任务逐步通过作业操作员#停止.
如果是习俗步实现想要处理外部停止信号,但就是做不到。
本版本新增了一个界面,名为可停止步,扩展为步并且可以通过任何能够处理停车信号的步骤实现。
优雅关机支持
Spring Batch6.0引入了对批处理作业优雅关闭的支持。该功能允许您以受控方式停止正在执行的作业,确保中断信号正确发送到正在运行的步骤。
当优雅地关闭时,作业执行会停止当前正在进行的步骤,并更新作业仓库,使其状态一致,从而实现可重启。一旦运行步骤完成,作业执行将被标记为停止,并执行必要的清理作。
JavaFlight Recorder(JFR)的可观测性
除了现有的微米指标外,Spring Batch 6.0还引入了对JavaFlight Recorder(JFR)的支持,以增强可观测性。
JFR 是一个强大的分析和事件收集框架,内置于 Java 虚拟机(JVM)。它让你能够以最小的性能开销捕捉应用程序运行时行为的详细信息。
本版本引入了多个JFR事件,用于监控批处理作业执行的关键方面,包括作业和步执行、项目读写以及事务边界。
使用 JSpecify 进行空安全注释
Spring Batch 6.0 API 现已标注 JSpecify 注释,以提供更好的空安全保障并提升代码质量。
局部分块支持
与远程分块类似,本地分块是一个新功能,允许你在同一JVM内用多个线程并行处理项目块。当你需要处理大量项目并希望利用多核处理器时,这尤其有用。通过本地分块,你可以配置一个块导向步骤,使用多个线程同时处理项目块。每个线程独立读取、处理和写入自己的项目块,而该步骤负责整体执行并提交结果。
SEDA 风格与 Spring Integration 消息通道
在春季5.2中,我们引入了SEDA(分阶段事件驱动架构)风格处理的概念,利用本地线程,并阻塞队列项目读取器和阻塞队列项目写作组件。 在此基础上,Spring Batch 6.0 引入了大规模支持 SEDA 风格处理,使用 Spring Integration 消息通道。这允许你将批处理作业的不同阶段解耦,并通过消息通道异步处理。通过利用 Spring Integration,你可以轻松配置和管理消息通道,并利用消息转换、过滤和路由等功能。
Jackson3号支持节目
Spring Batch 6.0 已升级,支持 Jackson 3.x 进行 JSON 处理。此次升级确保了与 Jackson 库中最新功能和改进的兼容性,同时提供更好的性能和安全性。Spring Batch 中所有与 JSON 相关的组件,例如JsonItemReader和JsonFileItemWriter,以及JacksonExecutionContextStringSerializer已更新为默认使用 Jackson 3.x。
Jackson 2.x 的支持已被弃用,并将在未来版本中移除。如果您目前在 Spring Batch 应用中使用 Jackson 2.x,建议升级到 Jackson 3.x,以享受最新功能和改进。
远程步进支持
本版本引入了远程步骤执行支持,允许您在远程机器或集群上执行批处理作业的步骤。此功能对于大规模批处理场景尤其有用,这些场景希望将工作负载分布到多个节点以提升性能和可扩展性。远程步骤执行通过 Spring Integration 消息通道实现,这些通道使本地作业执行环境与远程步骤执行者之间能够通信。
Lambda 风格配置
本版本引入了使用上下文λ表达式来配置批处理件件。这种新型配置方式为定义项目读写器提供了更简洁易读的方式。
例如,不像这样使用传统的建造者模式:
var reader = new FlatFileItemReaderBuilder()
.resource(...)
.delimited()
.delimiter(",")
.quoteCharacter('"')
...
.build();
你现在可以用λ表达式来配置分隔选项,比如这样:
var reader = new FlatFileItemReaderBuilder()
.resource(...)
.delimited (config -> config.delimiter(',').quoteCharcter( '"' ))
...
.build();
弃用与修剪
与所有重大版本一样,Spring Batch6.0中部分功能已被弃用或移除。以下变化值得注意:
-
之前版本中所有弃用的 API 和功能已被移除
-
模块化配置
@EnableBatchProcessing(模 = 真)已被弃用 -
本版本中弃用了若干 API,以简化核心 API 并缩小其范围
-
弃用 JUnit 4 在
Spring Batch测试模块 -
弃用Jackson 2
-
通过
批:。。。Namespace
更多细节请参阅迁移指南。