知識庫 / Spring / Spring Boot RSS 訂閱

Spring Batch 條件流

Spring Boot
HongKong
5
01:01 PM · Dec 06 ,2025

1. 簡介

我們使用 Spring Batch 來構建由多個步驟組成的作業,這些步驟負責讀取、轉換和寫入數據。如果作業中的步驟有多個路徑,類似於我們在代碼中使用 if 語句,我們稱之為作業流程為 條件型

在本教程中,我們將探討兩種創建具有條件流的 Spring Batch 作業的方法。

2. 退出狀態和批處理狀態

當我們在 Spring Batch 框架中指定一個條件步驟時,我們正在使用步驟或作業的退出狀態。因此,我們需要理解步驟和作業中的批處理狀態和退出狀態之間的區別:

  • BatchStatus 是一個枚舉,代表步驟/作業的狀態,並由 Batch 框架內部使用
  • 可能的取值包括:ABANDONED、COMPLETED、FAILED、STARTED、STARTING、STOPPED、STOPPING、UNKNOWN
  • ExitStatus 是步驟執行完成後,執行狀態,用於條件確定流程

默認情況下,步驟或作業的 ExitStatus 與其 BatchStatus 相同。 還可以設置自定義的 ExitStatus 以驅動流程。

3. 條件流程

假設我們有一個物聯網設備向我們發送測量數據。這些測量數據是整數數組,我們需要在任何測量數據包含正整數時發送通知。

換句話説,我們需要在檢測到正數測量值時發送通知。

3.1. 退出狀態 (ExitStatus)</h3

重要的是,我們使用步驟的退出狀態來驅動條件流程

要設置步驟的退出狀態,我們需要使用 StepExecution 對象的 setExitStatus 方法。為了做到這一點,我們需要創建一個擴展 ItemListenerSupportItemProcessor,並獲取步驟的 StepExecution

我們使用它將步驟的退出狀態設置為 NOTIFY,當我們找到一個正數時。 當我們根據批處理作業中的數據確定退出狀態時,我們可以使用 ItemProcessor

讓我們看看我們的 NumberInfoClassifier,以查看我們需要的方法:

public class NumberInfoClassifier extends ItemListenerSupport<NumberInfo, Integer>
  implements ItemProcessor<NumberInfo, Integer> {
 
    private StepExecution stepExecution;

    @BeforeStep
    public void beforeStep(StepExecution stepExecution) {
        this.stepExecution = stepExecution;
        this.stepExecution.setExitStatus(new ExitStatus(QUIET));
    }

    @Override
    public Integer process(NumberInfo numberInfo) throws Exception {
        return Integer.valueOf(numberInfo.getNumber());
    }

    @Override
    public void afterProcess(NumberInfo item, Integer result) {
        super.afterProcess(item, result);
        if (item.isPositive()) {
            stepExecution.setExitStatus(new ExitStatus(NOTIFY));
        }
    }
}

注意:在本例中,我們使用 ItemProcessor 來設置 ExitStatus,但我們也可以在步驟的 ItemReaderItemWriter 中輕鬆完成。

最後,當我們創建我們的 job 時,我們會告訴我們的 JobBuilder 以便為任何以 NOTIFY 狀態退出步驟發送通知。

new JobBuilder("Number generator - second dataset", jobRepository)
    .start(dataProviderStep)
    .on("NOTIFY").to(notificationStep)
    .end()
    .build();

此外,當我們在工作流程中包含額外的條件分支和多個退出代碼時,可以使用 JobBuilderfromon 方法將其添加到工作流程中。

new JobBuilder("Number generator - second dataset", jobRepository)
    .start(dataProviderStep)
    .on("NOTIFY").to(notificationStep)
    .from(step).on("LOG_ERROR").to(errorLoggingStep)
    .end()
    .build();

現在,每當我們的 ItemProcessor 看到一個正數時,它會指示我們的任務運行 notificationStep,該步驟只需將一條消息打印到 System.out

Second Dataset Processor 11
Second Dataset Processor -2
Second Dataset Processor -3
[Number generator - second dataset] contains interesting data!!

如果數據集中沒有包含正數,我們就不再會看到 notificationStep 消息:

Second Dataset Processor -1
Second Dataset Processor -2
Second Dataset Processor -3

3.2. 使用JobExecutionDecider進行程序化分支

或者,我們可以使用實現JobExecutionDecider的類來確定任務流程。這在我們有外部因素來確定執行流程時尤其有用

要使用此方法,我們首先需要修改我們的ItemProcessor,以移除ItemListenerSupport接口和@BeforeStep方法:

public class NumberInfoClassifierWithDecider extends ItemListenerSupport<NumberInfo, Integer>
  implements ItemProcessor<NumberInfo, Integer> {

    @Override
    public Integer process(NumberInfo numberInfo) throws Exception {
        return Integer.valueOf(numberInfo.getNumber());
    }
}

接下來,我們創建一個 decider 類,該類確定我們的步驟的通知狀態:

public class NumberInfoDecider implements JobExecutionDecider {

    private boolean shouldNotify() {
        return true;
    }

    @Override
    public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
        if (shouldNotify()) {
            return new FlowExecutionStatus(NOTIFY);
        } else {
            return new FlowExecutionStatus(QUIET);
        }
    }
}

然後,我們設置我們的 Job 使用流程中的決策器:

new JobBuilder("Number generator - third dataset", jobRepository)
    .start(dataProviderStep)
    .next(new NumberInfoDecider()).on("NOTIFY").to(notificationStep)
    .end()
    .build();

4. 結論

在本快速教程中,我們探討了兩種使用 Spring Batch 實現條件流程的方法。首先,我們研究瞭如何使用 ExitStatus 來控制我們的作業流程。

然後,我們研究瞭如何通過定義自己的 JobExecutionDecider 來程序化控制流程。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.