1. 序章

Spring Batch を使用して、データの読み取り、変換、書き込みを行う複数のステップからジョブを作成します。 コードでifステートメントを使用する場合と同様に、ジョブのステップに複数のパスがある場合、ジョブフローは条件付きであると言います。

このチュートリアルでは、条件付きフローを使用してSpringバッチジョブを作成する2つの方法を見ていきます。

2. 終了ステータスとバッチステータス

Springのバッチフレームワークで条件付きステップを指定する場合、ステップまたはジョブの終了ステータスを使用しています。 したがって、ステップとジョブのバッチステータスと終了ステータスの違いを理解する必要があります。

  • BatchStatus は、ステップ/ジョブのステータスを表す列挙型であり、Batchフレームワークによって内部的に使用されます
  • 可能な値は次のとおりです。ABANDONED、COMPLETED、FAILED、STARTED、STARTING、STOPPED、STOPPING、UNKNOWN
  • ExitStatus は、実行が完了したときのステップのステータスであり、条件付きでフローを決定するために使用されます

デフォルトでは、ステップまたはジョブのExitStatusはそのBatchStatusと同じです。 カスタムExitStatusを設定してフローを駆動することもできます。

3. 条件付きフロー

測定値を送信するIOTデバイスがあるとします。 デバイスの測定値は整数の配列であり、測定値のいずれかに正の整数が含まれている場合は通知を送信する必要があります。

つまり、陽性の測定値を検出したときに通知を送信する必要があります。

3.1. ExitStatus

重要なのは、ステップの終了ステータスを使用して条件付きフローを駆動することです。

ステップの終了ステータスを設定するには、StepExecutionオブジェクトのsetExitStatusメソッドを使用する必要があります。 そのためには、 ItemProcessor 伸びる ItemListenerSupport ステップのを取得します StepExecution

これを使用して、正の数が見つかったときにステップの終了ステータスをNOTIFYに設定します。 バッチジョブ内のデータに基づいて終了ステータスを決定する場合、ItemProcessorを使用できます。

NumberInfoClassifier を見て、必要な3つのメソッドを確認しましょう。

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を設定していますが、ステップのItemReaderまたはItemWriter[でも同じように簡単に設定できます。 X173X]。

最後に、ジョブを作成するときに、 JobBuilderFactory に、NOTIFYのステータスで終了するステップの通知を送信するように指示します。

jobBuilderFactory.get("Number generator - second dataset")
    .start(dataProviderStep)
    .on("NOTIFY").to(notificationStep)
    .end()
    .build();

また、追加の条件分岐と複数の終了コードがある場合、JobBuilderFacotryメソッドのfromおよびを使用してそれらをジョブに追加できることにも注意してください。

jobBuilderFactory.get("Number generator - second dataset")
    .start(dataProviderStep)
    .on("NOTIFY").to(notificationStep)
    .from(step).on("LOG_ERROR").to(errorLoggingStep)
    .end()
    .build();

これで、 ItemProcessor が正の数を検出すると、 notifyStep を実行するようにジョブに指示されます。これにより、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());
    }
}

次に、ステップの通知ステータスを決定する決定クラスを作成します。

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を設定します。

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

4. 結論

このクイックチュートリアルでは、SpringBatchを使用して条件付きフローを実装するための2つのオプションについて説明しました。 まず、ExitStatusを使用してジョブのフローを制御する方法を確認しました。

次に、独自の JobExecutionDecider を定義することにより、プログラムでフローを制御する方法を確認しました。

いつものように、記事の完全なソースコードは、GitHubから入手できます。