【初心者必見】Spring Batchの基本をおさらい

Spring

Spring Batchはバッチ処理を実装するにあたり、有力なフレームワークであり、一から自分で実装するよりはるかに手軽に実装することが可能です。

バッチ開発をJavaで実装するとなった際は、誰もが導入を検討するでしょう。

Springアプリを使っているプロジェクトならなおさらだね

ここで、Spring Batchの全体像について説明していきます。

Spring Batchの流れ

Spring Batchは主に以下のコンポーネントで構成されます。

  • Job Repository
  • Job Launcher
  • Job
  • Step

Job RepositoryはJobやStepを管理しており、定義された設定に基づいて失敗や再試行といったトランザクションを保証します。

デフォルトではインメモリで実行管理するけど、永続化が必要な場合はDBやスキーマを設定しないといけないよ。

ClientからコマンドなどでJobを実行した時に、Job LauncherがJobのパラメータ毎(実行日時など)にJob Instanceを作成します。

Jobは複数実装することが可能で、Job内にも複数のStepに分けて処理が施行されます。

例えば、①DBの初期化を行ってから、②ファイルを読み込んで、③データに変更を加えたり、、などですね。

では、具体的にどのように実装するのでしょうか?

Stepの定義方法

Stepの定義方法が、以下の2つになります。

  • Tasklet
  • Chunk

ここでは、分かりやすいようにStep1をTasklet、Step2をChunkで実装するパターンについて考えてみましょう。

Tasklet

Step1で定義したTaskletでは、Chunk(データのIO処理など)には当てはまらない処理をしたい場合に利用します。

Spring Batchが提供するインターフェースなので、以下のようにimplementsして使用します。

@Component("jobATasklet")
@Scope("step")
public class jobATasklet implements Tasklet {
  @Override
  public RepeatStatus execute(StepContribution contribution,
			ChunkContext chunkContext) throws Exception {
    ...
    return RepeatStatus.FINISHED;
  }
}

Chunk

Step2で定義したChunkは、以下3つのItemをセットで一つのトランザクションとします。

  • ItemReader:データの読み込み
  • ItemProcessor:業務処理
  • ItemWriter:データの書き込み

こちらも、それぞれSpring Batchが提供しているインターフェースなので、以下のようにimplementsして使用します。

public class TestItemReader implements ItemReader<I>, StepExecutionListener {
  @Override
  public I read() throws Exception {
  ...
  }
}
public class TestItemProcessor implements ItemProcessor<I, O>, StepExecutionListener {
  @Override
  public O process(I item) throws Exception{
  ...
  }
public class TestItemWriter<T> implements ItemWriter<O>, StepExecutionListener {
  @Override
  public void write(List<? extends O> items) throws Exception {
  ...
  }

Configurationのやり方

ここまで、Stepの処理内容の実装方法について説明しましたが、Stepの実施手順(順番など)をJob毎に定義する必要があります。その定義の仕方にJavaベースとXMLベースの2種類があります。

これまでの例と同様にStep1をTasklet、Step2をChunkとした場合、それぞれ以下のような実装になります。

Java-based Configuration

@Configuration
@EnableBatchProcessing
public class MyJobConfiguration {
  @Bean
  public Job jobA(JobRepository jobRepository, Step step1, Step step2) {
    return new JobBuilder("jobA", jobRepository)
                .start(step1)
        .next(step2)
                .build();
  }
  @Bean
  public Step step1(JobRepository jobRepository, PlatformTransactionManager
  transactionManager) {
    return new StepBuilder("step1", jobRepository)
    			.tasklet(jobATasklet(), transactionManager)
    			.build();
  @Bean
  public Step step2(JobRepository jobRepository, 
		PlatformTransactionManager transactionManager) { 
	return new StepBuilder("step2", jobRepository)
				.<String, String>chunk(10, transactionManager) 
				.reader(itemReader())
                                .processor(itemProcessor())
				.writer(itemWriter())
				.build();
}

XML-based Config

<job id="jobA" job-repository="jobRepository"> 
    <step id="step1">
       <tasklet ref="jobATasklet" transaction-manager="transactionManager"/>
    </step>
    <step id="step2">
        <tasklet transaction-manager="transactionManager"> 
            <chunk reader="itemReader" processor="itemProcessor" writer="itemWriter" commit-interval="10"/> 
        </tasklet>
    </step>
</job>

Listenerとは

ListenerとはJobやStepの実行前後で処理を実装するためのもので、ログの出力やステータスに応じた処理を組み込むことができます。

主に以下の種類があります。

  • JobExecutionListener
  • StepExecutionListener
  • ChunkListener
  • Item[Read/Process/Write]Listener

以下はStepExecutionListenerをimplementsした例になります。

@Configuration
public class TestLoggingListener implements StepExecutionListener {

  @Override
  public void beforeStep(StepExecution stepExecution) {
    ...
  }

  @Override
  public ExitStatus afterStep(StepExecution stepExecution) {
    ...
    return stepExecution.getExitStatus();
  }

}

Jobの実行

以下のapplication.ymlの設定をfalseにしないと、アプリ起動時に自動的にJobが実行されてしまいます。

spring.batch.job.enabled = false

Jobの実行にはJavaコマンドでComandLineJobRunnerから起動する他に、監視処理からJobOperatorで起動する方法があるようです。

以下はJavaコマンドでJobを実行する際のコマンドの例です。

java -jar {jar名} {batchのxmlファイル} {Job名} {パラメータ名=値}

set tmptime=%Time: =0%
java -jar test-batch.jar testJob.xml jobA file=testdata.csv datetime=%DATE:~-10,4%%DATE:~-5,2%%DATE:~-2%%tmptime:~0,2%%tmptime:~3,2%%tmptime:~6,2%

最後に

Spring Batchにある多彩な機能を網羅するのは大変ですね。

基本を押さえて開発することで、ぐんっと成長の幅も広がると思うので、ここで一度作っているシステムを見返してみるのも良いかもしれません。

参考文献

JobLauncher の構成 :: Spring Batch – リファレンス

タイトルとURLをコピーしました