Spring Batch 5.0 正式發佈!

發佈 | Mahmoud Ben Hassine | 2022 年 11 月 24 日 | ...

它終於來了!Spring Batch 5.0 現在已在 Maven Central 上正式發佈。 Spring Batch 5 是兩年工作的結晶,包含了 50 多位貢獻者的數十項改進、功能和錯誤修復! 我謹代表團隊,感謝所有在此重大版本中做出貢獻的人!

這篇部落格文章將介紹這個新一代框架的主要亮點。您可以在發佈說明中找到所有變更的詳細資訊,並在遷移指南中找到升級說明。

新功能?

  • 新的 Java 版本基準
  • 主要相依性升級
  • 完整的 GraalVM Native 支援
  • Micrometer 中引入新的 Observation API
  • 執行內容中繼資料改進
  • 新的預設執行內容序列化格式
  • SystemCommandTasklet 增強功能
  • 新增支援使用任何類型作為 Job 參數
  • 改進的 Job 參數轉換
  • EnableBatchProcessing 中的新註解屬性
  • 基礎架構 Bean 的新配置類別
  • JobExplorer 和 JobOperator 中的事務支援
  • 使用 EnableBatchProcessing 自動註冊 JobOperator
  • 測試工具程式配置更新
  • 遷移至 JUnit Jupiter
  • Java Records 支援改進
  • 預設使用 UTF-8
  • Java 8 功能更新
  • 新的 Maven 材料清單
  • 完整的 MariaDB 支援
  • 支援將 SAP HANA 作為 Job 儲存庫
  • 改進的說明文件

新的 Java 版本基準

Spring Batch 遵循 Spring Framework 的 Java 版本和第三方相依性的基準。 隨著 Spring Batch 5 的發佈,Spring Framework 版本將升級至 Spring Framework 6,這需要 Java 17。 因此,Spring Batch 的 Java 版本要求也將提高到 Java 17。

主要相依性升級

為了繼續與 Spring Batch 使用的第三方函式庫的支援版本整合,Spring Batch 5 正在全面更新相依性至以下版本

  • Spring Framework 6
  • Spring Integration 6
  • Spring Data 3
  • Spring AMQP 3
  • Spring for Apache Kafka 3
  • Micrometer 1.10

此版本也標誌著遷移至

  • Jakarta EE 9
  • Hibernate 6

完整的 GraalVM Native 支援

使用 GraalVM native-image 編譯器將 Spring Batch 應用程式編譯為原生可執行檔的努力始於 v4.2,並在 v4.3 中以實驗性形式發佈。

在此版本中,透過提供必要的預先(Ahead-Of-Time)處理和執行階段提示,以便使用 GraalVM 原生編譯 Spring Batch 應用程式,原生支援得到了顯著改進。

在這篇部落格文章中,我們想與您分享我們在這個領域進行的一些基準測試。 以下基準測試基於來自 Spring Native 範例專案的 batch 範例。 這些基準測試顯示了使用常規 JVM 執行以及作為原生可執行檔執行的相同批次應用程式的啟動時間和總執行時間的比較

perf-native

此處顯示的值是使用以下軟體和硬體設定的範例執行 10 次的平均值

  • JVM:OpenJDK 版本 "17" 2021-09-14
  • GraalVM:OpenJDK 執行環境 GraalVM CE 22.0.0.2
  • MacOS BigSur v11.6.2 (CPU:2,4 GHz 8 核心 Intel Core i9,記憶體:32 GB 2667 MHz DDR4)

正如這些基準測試所示,原生 Spring Batch 應用程式的啟動速度快倍,執行速度快近 倍! 這對於雲端原生批次工作負載來說,真的是一個改變遊戲規則的因素!

Micrometer 中引入新的 Observation API

隨著升級到 Micrometer 1.10,您現在除了 Batch 指標之外,還可以獲得 Batch 追蹤。 Spring Batch 將為每個 Job 建立一個 span,並為 Job 中的每個 Step 建立一個 span。 此追蹤中繼資料可以收集並在儀表板上查看,例如 Zipkin

此外,此版本還引入了新的指標

  • job.launch.count:這是一個 Counter,用於報告透過 JobLauncher 啟動了多少個 Job。 這對於批次 Job 在持續執行的 JVM 中排程和執行的環境非常方便。
  • step.active:此類型為 LongTaskTimer 的指標報告特定 Job 中目前作用中(即正在執行)的 Step。 此指標適用於 Job 有多個 Step 並且想要知道目前正在處理哪個 Step 的情況。

執行內容中繼資料改進

除了 Spring Batch 已經在執行內容中持久保存的與執行階段資訊(例如 Step 類型、重新啟動標誌等)有關的資訊之外,此版本還在執行內容中新增了一個重要細節,即用於序列化執行內容的 Spring Batch 版本。

雖然這似乎是一個細節,但在除錯與執行內容序列化和還原序列化有關的升級問題時,它具有巨大的附加價值。

新的預設執行內容序列化格式

在此版本中,DefaultExecutionContextSerializer 已更新為將執行內容序列化/從 Base64 還原序列化。

此外,由 @EnableBatchProcessingDefaultBatchConfiguration 配置的預設 ExecutionContextSerializer 已從 JacksonExecutionContextStringSerializer 變更為 DefaultExecutionContextSerializer。 現在對 Jackson 的相依性是可選的。 為了使用 JacksonExecutionContextStringSerializer,應將 jackson-core 新增到類別路徑。

SystemCommandTasklet 的增強

在此版本中,SystemCommandTasklet 已重新檢視並進行了以下變更:

  • 引入了一個名為 CommandRunner 的新策略介面,以便將命令執行與 tasklet 執行分離。預設的實作是 JvmCommandRunner,它使用 java.lang.Runtime#exec API 來執行系統命令。可以實作此介面以使用任何其他 API 來執行系統命令。

  • 現在,執行命令的方法接受一個 String 陣列,代表命令及其引數。不再需要對命令進行符號化或進行任何預處理。此變更使 API 更加直觀,並且更不容易出錯。

新增支援將任何類型用作 Job 參數

在 4.x 版本之前,Spring Batch 僅支援 4 種可以用作 Job 參數的類型,分別是 longdoubleStringDate。雖然這簡化了 framework 端 Job 參數的處理,但這對使用者端而言是一種限制。例如,如果想要使用 boolean 或自訂類型作為 Job 參數怎麼辦?這需要額外轉換為 Spring Batch 中支援的類型之一,這很快就變得對使用者不方便。

在此版本中,我們新增了支援將任何類型用作 Job 參數。此改進背後的主要變更是以下內容:

---public class JobParameter implements Serializable {
+++public class JobParameter<T> implements Serializable {

---   private Object parameter;
+++   private T value;

---   private ParameterType parameterType;
+++   private Class<T> type;

}

此變更會影響 Job 參數在資料庫中的持久化方式。請檢查遷移指南,了解資料庫綱要變更。參數類型的完整名稱現在會以 String 形式持久化,參數值也是如此。字串文字會使用標準 Spring 轉換服務轉換為參數類型。可以使用任何所需的轉換器來豐富標準轉換服務,以便將使用者特定類型轉換為字串文字並從字串文字轉換。

改進的 Job 參數轉換

v4 中 Job 參數的預設表示法指定如下:

[+|-]parameterName(parameterType)=parameterValue

其中 parameterType[string,long,double,date] 之一。雖然此表示法很簡潔,但它顯示出幾個限制,因為它與環境變數的搭配效果不佳,並且對 Spring Boot 不友善。

在 v5 中,我們將預設表示法變更如下:

parameterName=parameterValue,parameterType,identificationFlag

其中 parameterType 是參數類型的完整名稱。例如,以下鍵/值對

schedule.date=2022-12-12,java.time.LocalDate

將轉換為類型為 java.time.LocalDate 且值為 2022-12-12 的識別 Job 參數。請注意,識別旗標是可選的,預設為 true。這種新的預設表示法非常適合大多數使用案例,但當值包含逗號時可能不太方便。因此,我們引入了一種新的「擴充」表示法,其靈感來自 Spring Boot 的 Json 應用程式屬性,並且指定如下:

parameterName='{"value": "parameterValue", "type":"parameterType", "identifying": "booleanValue"}'

其中 parameterType 是參數類型的完整名稱。Spring Batch 提供了 JsonJobParametersConverter 來支援此表示法。當然,也可以透過實作策略介面 JobParametersConverter 並在 Job 儲存庫和 Job 瀏覽器中註冊自訂實作來支援任何其他表示法。

我們相信 Spring Batch 中 Job 參數處理的這兩項主要變更更方便、更靈活且更不容易出錯。

EnableBatchProcessing 中的新註解屬性

在此版本中,@EnableBatchProcessing 註解引入了新的屬性,用於指定應該使用哪些元件和參數來配置 Batch 基礎結構 bean。例如,您現在可以指定 Spring Batch 應該在 Job 儲存庫中配置哪個資料來源和交易管理器。以下程式碼片段顯示了執行此類配置的新方法

@Configuration
@EnableBatchProcessing(dataSourceRef = "batchDataSource", transactionManagerRef = "batchTransactionManager")
public class MyJobConfiguration {

	@Bean
	public Job job(JobRepository jobRepository) {
		return new JobBuilder("myJob", jobRepository)
			 //define job flow as needed
			 .build();
	}

}

在此範例中,batchDataSourcebatchTransactionManager 指的是應用程式環境定義中的 bean,這些 bean 用於配置 Job 儲存庫和 Job 瀏覽器。您不再需要定義自訂的 BatchConfiguer,此版本已將其移除。例如,在 Spring Batch v4 中提供自訂的執行環境定義序列化器可以透過提供自訂的 BatchConfigurer 來實現,如下所示

@Configuration
@EnableBatchProcessing
public class MyJobConfigWithCustomSerializer {

    @Bean
    public BatchConfigurer batchConfigurer() {
        return new DefaultBatchConfigurer() {
            @Override
            public JobRepository getJobRepository() {
                JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
                factory.setSerializer(createCustomSerializer());
                // set other properties on the factory bean
                try {
                    factory.afterPropertiesSet();
                    return factory.getObject();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }

            @Override
            public JobExplorer getJobExplorer() {
                JobExplorerFactoryBean factoryBean = new JobExplorerFactoryBean();
                factoryBean.setSerializer(createCustomSerializer());
                // set other properties on the factory bean
                try {
                    factoryBean.afterPropertiesSet();
                    return factoryBean.getObject();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }

            private ExecutionContextSerializer createCustomSerializer() {
                Jackson2ExecutionContextStringSerializer serializer = new Jackson2ExecutionContextStringSerializer();
                // customize serializer
                return serializer;
            }
        };
    }

}

在 Spring Batch v5 中,您可以如下提供自訂的序列化器

@Configuration
@EnableBatchProcessing(executionContextSerializerRef = "myCustomSerializer")
public class MyJobConfigWithCustomSerializer {

    @Bean
    public Job job(JobRepository jobRepository) {
        return new JobBuilder("myJob", jobRepository)
                //define job flow as needed
                .build();
    }
    
    @Bean
    public ExecutionContextSerializer myCustomSerializer() {
        Jackson2ExecutionContextStringSerializer serializer = new Jackson2ExecutionContextStringSerializer();
        // customize serializer
        return serializer;
    }

}

我們相信這種配置 Spring Batch 的新方法更直觀、更直接且更不容易出錯。

基礎結構 Bean 的新配置類別

在此版本中,您可以使用一個名為 DefaultBatchConfiguration 的新配置類別,作為使用 @EnableBatchProcessing 來配置基礎結構 bean 的替代方法。此類別提供了具有預設配置的基礎結構 bean,您可以根據需要進行自訂。以下程式碼片段顯示了此類別的典型用法

@Configuration
class MyJobConfiguration extends DefaultBatchConfiguration {

	@Bean
	public Job job(JobRepository jobRepository) {
		return new JobBuilder("myJob", jobRepository)
				//define job flow as needed
				.build();
	}

}

在此範例中,注入到 Job bean 定義中的 JobRepository bean 是在 DefaultBatchConfiguration 類別中定義的。您可以透過覆寫相應的 getter 來指定自訂參數。例如,以下範例顯示了如何覆寫 Job 儲存庫和 Job 瀏覽器中使用的預設字元編碼

@Configuration
class MyJobConfiguration extends DefaultBatchConfiguration {

	@Bean
	public Job job(JobRepository jobRepository) {
		return new JobBuilder("job", jobRepository)
				// define job flow as needed
				.build();
	}

	@Override
	protected Charset getCharset() {
		return StandardCharsets.ISO_8859_1;
	}
}

JobExplorer 和 JobOperator 中的交易支援

此版本在透過 JobExplorerFactoryBean 建立的 JobExplorer 中引入了交易支援。您現在可以指定要使用哪個交易管理器來驅動查詢 Batch meta-data 時的唯讀交易。此外,您現在可以自訂交易屬性。透過一個名為 JobOperatorFactoryBean 的新 factory bean,相同的交易支援已新增到 JobOperator

使用 EnableBatchProcessing 自動註冊 JobOperator

從 4.x 版本開始,EnableBatchProcessing 註解提供了啟動 Spring Batch Job 所需的所有基本基礎結構 bean。但是,它沒有註冊 Job Operator bean,這是停止、重新啟動和放棄 Job 執行的主要進入點。

雖然這些實用程式的使用頻率不如啟動 Job,但在應用程式環境定義中自動新增 Job Operator 可能有助於避免最終使用者手動配置此類 bean。

測試實用程式配置更新

在 4.3 版之前,JobLauncherTestUtils 用於自動注入受測 Job,以方便測試設定。但是,如果在測試環境定義中定義了多個 Job 怎麼辦?如果根本沒有定義任何 Job bean 怎麼辦?因此,雖然這種自動注入對於大多數情況都很方便,但在上述情況下卻造成了一些問題。在此版本中,並且基於社群的回饋,我們決定移除 JobLauncherTestUtils 中任何 Job 的自動注入。

同樣地,JobRepositoryTestUtils 用於從應用程式環境定義中自動注入 DataSource。同樣地,如果在測試環境定義中沒有定義資料來源或定義了多個資料來源怎麼辦?在此版本中,JobRepositoryTestUtils 已更新為針對 JobRepository 介面運作,而無需處理儲存庫的任何實作細節(例如資料來源)。

如果您在測試環境中手動定義這些公用程式 Bean,或者透過 @SpringBatchTest 匯入它們,當您的測試環境中定義了多個這些類型的 Bean 時,您需要手動設定受測的 Job 或測試資料來源。

遷移至 JUnit Jupiter

在這個版本中,Spring Batch 的整個測試套件已遷移至 JUnit 5。 雖然這不會直接影響終端使用者,但有助於 Batch 團隊和社群貢獻者使用下一代的 JUnit 來編寫更好的測試。

Java Records 支援改進

最初在 v4.3 中引入了對 Java records 作為 chunk-oriented step 中 items 的支援,但由於 v4 以 Java 8 作為基準,因此該支援受到限制。 在 Java 8 中,records 甚至還沒有預覽版。 最初的支援是基於 reflection 的技巧來建立 Java records 並使用資料填充它們,而無法存取 java.lang.Record API,該 API 已在 Java 16 中最終確定。

現在 v5 以 Java 17 作為基準,我們透過利用框架不同部分的 java.lang.Record API,改進了 Spring Batch 中的 records 支援。 例如,FlatFileItemReaderBuilder 現在能夠檢測 item 類型是 record 還是常規類別,並相應地設定對應的 FieldSetMapper 實作(record 使用 RecordFieldSetMapper,常規類別使用 BeanWrapperFieldSetMapper)。 這裡的目標是讓使用者 *透明* 地設定所需的 FieldSetMapper 類型。 同樣的功能也在 FlatFileItemWriterBuilder 中實現,以便根據 item 類型設定 RecordFieldExtractorBeanWrapperFieldExtractor

預設使用 UTF-8

多年來,已在框架的不同領域報告了幾個與字元編碼相關的問題,例如基於檔案的 item readers 和 writers 之間預設編碼不一致、在執行內容中處理多位元組字元時出現序列化/反序列化問題等等。

JEP 400 精神一致,並遵循 UTF-8 manifesto,我們已將框架所有領域的預設編碼更改為 UTF-8,並在適當的情況下使此預設值可配置。

Java 8 功能更新

我們藉此主要版本更新的機會,使用 Java 8+ 的功能來改進程式碼庫,例如

  • 在介面中使用預設方法並棄用 "support" 類別 (請參閱 issue 3924)
  • 在公用 API 中適當的地方新增 @FunctionalInterface (請參閱 issue 4107)
  • 新增對使用 Date and Time APIs 中的類型作為 job 參數的支援。(請參閱 issue 1035)

新的 Maven Bill of Materials

這個功能已經被要求多次,並且終於在此版本中發布。 現在可以使用新增加的 Maven BOM 來匯入具有一致版本號碼的 Spring Batch 模組。

完整的 MariaDB 支援

在 v4.3 之前,Spring Batch 透過將 MariaDB 視為 MySQL 來提供對它的支援。 在這個版本中,MariaDB 現在被視為一個獨立的資料庫產品,具有自己的 DDL 腳本和 DataFieldMaxValueIncrementer

支援 SAP HANA 作為 job 儲存庫

SAP Hana 現在已正式支援作為 Spring Batch 中的 job 儲存庫。

改進的文件

在這個版本中,文件已更新為使用 Spring Asciidoctor Backend。 這個 backend 確保了來自 portfolio 的所有專案都遵循相同的文件樣式。 為了與其他專案保持一致,Spring Batch 的參考文件已更新為在這個版本中使用這個 backend。 您可以在 這裡 查看參考文件的新版本。

哪些已被棄用或移除?

在這個主要版本中,所有在先前版本中被棄用的 API 都已被移除。 此外,一些 API 已在 v5.0 中被棄用,並計劃在 v5.2 中移除。 最後,出於實際原因,一些 API 已被移動或移除,而沒有被棄用。 有關所有已棄用的 API 的列表,請參閱遷移指南

SQLFire 支援移除

SqlFire 已宣布於 2014 年 11 月 1 日終止服務 (EOL)。對 SQLFire 作為 job 儲存庫的支援已在 v4.3 版本中被棄用,並在 v5.0 版本中被移除。

GemFire 支援移除

基於 停止支援 Spring Data for Apache Geode 的決定,已移除 Spring Batch 中對 Apache Geode 的支援。

該程式碼已移至 spring-batch-extensions 儲存庫,作為社群驅動的努力。

JSR-352 實作移除

由於缺乏採用,已在這個版本中停止 JSR-352 的實作。

已修復了什麼?

有些錯誤無法在不引入重大變更的情況下修復。 我們藉此主要版本更新的機會來修復這些錯誤。 請參閱發布說明,以取得在此版本中修復的 40 多個錯誤的完整列表!

意見反應與貢獻

我要感謝所有在這個大型版本中做出貢獻的人! 如果沒有 Spring 社群,特別是 Spring Batch 社群的幫助,這個版本是不可能實現的。 我們很樂意聽到您對這個主要版本的反饋,以及它如何改進您的批次基礎架構。 請在 GithubTwitterStackOverflow 上提交您的反饋。

接下來是什麼?

由於我們剛剛發布了下一代 Spring Batch 的第一個版本,我們仍然有很多想法和功能正在開發中,或者計劃在下一個版本中開發,例如

  • chunk-oriented 處理模型的新實作
  • 基於 Java 19 虛擬線程的新並發模型
  • 基於 MongoDB 的新 job repository 實作
  • 還有更多!

我們將在不久的將來與您分享我們的完整路線圖,並向您展示如何參與這些新功能的早期開發和測試階段。 請繼續關注!


Spring Batch 首頁 | Github 上的原始碼 | 參考文件

訂閱 Spring 電子報

與 Spring 電子報保持聯繫

訂閱

取得領先

VMware 提供培訓和認證,以加速您的進程。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中為 OpenJDK™、Spring 和 Apache Tomcat® 提供支援和二進位檔。

了解更多

即將舉辦的活動

查看 Spring 社群中所有即將舉辦的活動。

查看全部