Spring Batch 5.2 的新特性
本節重點介紹 Spring Batch 5.2 的主要變更。有關完整的變更列表,請參閱釋出說明。
Spring Batch 5.2 包含以下特性
依賴升級
在此版本中,Spring 依賴項升級到以下版本
-
Spring Framework 6.2.0
-
Spring Integration 6.4.0
-
Spring Data 3.4.0
-
Spring Retry 2.0.10
-
Spring LDAP 3.2.8
-
Spring AMQP 3.2.0
-
Spring Kafka 3.3.0
-
Micrometer 1.14.1
支援 MongoDB 作業倉庫
此版本引入了首個由 MongoDB 支援的 NoSQL 作業倉庫實現。與關係型作業倉庫實現類似,Spring Batch 提供了一個指令碼用於在 MongoDB 中建立必要的集合,以儲存和檢索批處理元資料。
此實現需要 MongoDB 4 或更高版本,並基於 Spring Data MongoDB。要使用此作業倉庫,您只需定義一個 MongoTemplate
和一個 MongoTransactionManager
,它們是新增的 MongoJobRepositoryFactoryBean
所需的。
@Bean
public JobRepository jobRepository(MongoTemplate mongoTemplate, MongoTransactionManager transactionManager) throws Exception {
MongoJobRepositoryFactoryBean jobRepositoryFactoryBean = new MongoJobRepositoryFactoryBean();
jobRepositoryFactoryBean.setMongoOperations(mongoTemplate);
jobRepositoryFactoryBean.setTransactionManager(transactionManager);
jobRepositoryFactoryBean.afterPropertiesSet();
return jobRepositoryFactoryBean.getObject();
}
定義了 MongoDB 作業倉庫後,您可以將其作為常規作業倉庫注入到任何作業或步驟中。您可以在 MongoDBJobRepositoryIntegrationTests 中找到完整的示例。
新的無資源作業倉庫
在 v5 中,出於多種原因,基於 Map 的記憶體作業倉庫實現被移除。Spring Batch 中唯一剩餘的作業倉庫實現是 JDBC 實現,它需要一個數據源。雖然這與 H2 或 HSQLDB 等記憶體資料庫配合良好,但對於許多習慣於使用基於 Map 的倉庫而無需額外依賴的社群使用者來說,要求提供資料來源是一個強烈的限制。
在此版本中,我們引入了一個 JobRepository
實現,它不使用或儲存任何形式的批處理元資料(甚至不在記憶體中)。它是一個“無操作”(NoOp)實現,會丟棄批處理元資料且不與任何資源互動(因此得名“無資源作業倉庫”,借鑑自“無資源事務管理器”)。
此實現適用於不需要重啟以及執行上下文未以任何方式參與的用例(例如,透過執行上下文在步驟之間共享資料,或在分割槽步驟中透過執行上下文在管理器和工作節點之間共享分割槽元資料等)。
此實現適用於在自己的 JVM 中執行的一次性作業。它適用於事務性步驟(例如,使用 DataSourceTransactionManager
配置)以及非事務性步驟(使用 ResourcelessTransactionManager
配置)。此實現非執行緒安全,不應在任何併發環境中使用。
複合 Item Reader 實現
與 CompositeItemProcessor
和 CompositeItemWriter
類似,我們引入了一個新的 CompositeItemReader
實現,旨在按順序從具有相同格式的多個源讀取資料。當資料分散在不同的資源中且編寫自定義 Reader 不可行時,這非常有用。
CompositeItemReader
的工作方式與其他複合製品類似,透過按順序將讀取操作委託給常規 Item Reader。這是一個快速示例,展示了一個複合 Reader,它首先從平面檔案讀取人員資料,然後從資料庫表讀取。
@Bean
public FlatFileItemReader<Person> itemReader1() {
return new FlatFileItemReaderBuilder<Person>()
.name("personFileItemReader")
.resource(new FileSystemResource("persons.csv"))
.delimited()
.names("id", "name")
.targetType(Person.class)
.build();
}
@Bean
public JdbcCursorItemReader<Person> itemReader2() {
String sql = "select * from persons";
return new JdbcCursorItemReaderBuilder<Person>()
.name("personTableItemReader")
.dataSource(dataSource())
.sql(sql)
.beanRowMapper(Person.class)
.build();
}
@Bean
public CompositeItemReader<Person> itemReader() {
return new CompositeItemReader<>(Arrays.asList(itemReader1(), itemReader2()));
}
新的 java.util.function API 介面卡
與將 java.util.function.Function
適配為 Item Processor 的 FucntionItemProcessor
類似,此版本為其他 java.util.function
介面(如 Supplier
、Consumer
和 Predicate
)引入了幾個新的介面卡。
新增的介面卡包括:SupplierItemReader
、ConsumerItemWriter
和 PredicateFilteringItemProcessor
。有關這些新介面卡的更多詳細資訊,請參閱 org.springframework.batch.item.function 包。
使用阻塞佇列 Item Reader 和 Writer 實現併發步驟
分階段事件驅動架構 (SEDA) 是一種強大的架構風格,用於在透過佇列連線的階段中處理資料。由於 Spring Batch 能夠將作業設計為一系列步驟,這種風格可以直接應用於資料管道並輕鬆實現。
這裡唯一缺少的部分是如何從中間佇列讀取資料並向其寫入資料。此版本引入了一個 Item Reader 和一個 Item Writer,用於從 BlockingQueue
讀取資料並向其寫入。有了這兩個新類,可以設計第一個步驟將資料準備到佇列中,然後設計第二個步驟從同一佇列消費資料。這樣,兩個步驟可以併發執行,以非阻塞、事件驅動的方式高效處理資料。
JPA Item Reader 中的查詢提示支援
在 5.1 版本之前,JPA 遊標和分頁 Item Reader 不支援查詢提示(如 fetch size、timeout 等)。使用者需要提供自定義查詢提供程式來指定自定義提示。
在此版本中,JPA Reader 及其各自的構建器已更新,以在定義要使用的 JPA 查詢時接受查詢提示。
JDBC Item Reader 中的資料類支援
此版本在 JDBC 遊標和分頁 Item Reader 的構建器中引入了一個新方法,允許使用者在專案型別為資料類(Java Record 或 Kotlin Data Class)時指定 DataClassRowMapper
。
新方法 dataRowMapper(TargetType.class)
與 beanRowMapper(TargetType.class)
類似,旨在使常規類(Java Bean)和資料類(Java Record)之間的行對映器配置保持一致。
RecursiveCollectionLineAggregator 中可配置的行分隔符
到目前為止,RecursiveCollectionLineAggregator
中的行分隔符屬性一直設定為系統的行分隔符值。雖然可以透過系統屬性更改該值,但這種配置方式與批處理製品的其他屬性不一致。
此版本在 RecursiveCollectionLineAggregator
中引入了一個新的 setter,允許使用者配置自定義的行分隔符值,而無需使用系統屬性。
作業註冊改進
在 5.1 版本中,批處理基礎設施 Bean 的預設配置已更新,透過在應用程式上下文中定義 JobRegistryBeanPostProcessor
Bean 來自動填充作業登錄檔。在 Spring Framework 中最近對 BeanPostProcessorChecker
的日誌級別進行了更改後,典型的 Spring Batch 應用程式會記錄與 JobRegistryBeanPostProcessor
相關的多個警告。這些警告是由於 JobRegistryBeanPostProcessor
對 JobRegistry
Bean 存在依賴,這是不推薦的,並且可能導致 Bean 生命週期問題。
這些問題在此版本中已透過更改填充 JobRegistry
的機制得到解決,從使用 BeanPostProcessor
改為使用 SmartInitializingSingleton
。JobRegistryBeanPostProcessor
現已被棄用,推薦使用新增的 JobRegistrySmartInitializingSingleton
。