仕事で運用しているシステムが Spring Batch で動いているのですが、基本的な仕組みを押さえられていなかったので改めて入門してみようと思います。WebとかAPIとかはネットの情報も多いですが、Batchは使用場面が限られるせいか調べてもあまり出てこない印象です。
Spring Batch とは?
大量の処理をまとめて実行する「バッチ処理」が作りやすくなるフレームワークです。SpringのDIコンテナなどの機能のおかげで少ないコードで実装でき、様々なカスタマイズも可能です。
![Figure 2.1: Batch Stereotypes](https://spring.pleiades.io/spring-batch/docs/current/reference/html/images/spring-batch-reference-model.png)
構成はこのようになっていますが、まずは「2つの処理のステップを持つジョブを実行させる」最小限のサンプルを作成していきます。
プロジェクトのひな型を作成する
Springプロジェクトのひな型は Spring Initializr で簡単に作ることができます。今回は「sample-batch」というGradleプロジェクトを作成し、依存関係に Spring Batch とそのジョブ管理で必要となる H2 Database を追加しておきます。
![](https://restartmylife35.com/wp-content/uploads/2021/11/image-1-1024x845.png)
作成したプロジェクトには以下の Spring Boot のアプリケーション起動のクラスのみ存在します。
@SpringBootApplication
public class SampleBatchApplication {
public static void main(String[] args) {
SpringApplication.run(SampleBatchApplication.class, args);
}
}
Spring Boot のジョブを作成する
Spring Boot ではジョブと呼ばれる単位で処理を行い、そのジョブには複数のステップを実装することができます。
ステップの実装方法には簡潔なタスクレット(Tasklet)とデータの読み書きが付いたチャンク(Chunk)の2通りがありますが、今回はタスクレットを使用します。Taskletインタフェースを実装したTasklet1とTasklet2を以下のように作成します。
@Component
public class Tasklet1 implements Tasklet {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext)
throws Exception {
System.out.println("Tasklet1 が実行されました。");
return RepeatStatus.FINISHED;
}
}
@Component
public class Tasklet2 implements Tasklet {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext)
throws Exception {
System.out.println("Tasklet2 が実行されました。");
return RepeatStatus.FINISHED;
}
}
実装する必要があるのはexecuteメソッドだけで、メッセージの標準出力と処理終了のステータスの返却のみを行います。
@Component
@EnableBatchProcessing
public class SampleJobConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Step step1(Tasklet tasklet1) {
return stepBuilderFactory.get("step1").tasklet(tasklet1).build();
}
@Bean
public Step step2(Tasklet tasklet2) {
return stepBuilderFactory.get("step2").tasklet(tasklet2).build();
}
@Bean
public Job sampleJob(Step step1, Step step2) {
return jobBuilderFactory.get("sampleJob").start(step1).next(step2).build();
}
}
そして作成したタスクレットを用いてジョブを組み立てます。ジョブとステップの作成にはJobBuilderFactoryとStepBuilderFactoryが必要で、これらは@EnableBatchProcessingを付与すると@Autowiredで取得できるようになります。
step1とstep2をTasklet1とTasklet2から作成し、Beanを生成します。そしてそのBeanを用いてsampleJobという名前のジョブを作成し、こちらもBeanを生成します。
作成したジョブを実行する
これだけの実装でもうジョブを実行できるようになっています。Boot Dashboard からアプリを実行すると、以下のように2つのステップ(タスクレット)が実行されたことが分かります。
![](https://restartmylife35.com/wp-content/uploads/2021/11/image-2-1024x121.png)
Spring Batch はデフォルトだとBean登録されたジョブを自動で実行してくれるんですね。裏ではジョブの登録やステップ実行の管理など色んな処理が行われているのですが、それらを意識する必要がなく動くものを作ることができました。
次回以降はこれをベースに Spring Batch の仕組みを少しずつ確認していきたいと思います。