08.バッチ処理の実際のサンプル
(tasklet処理、条件分岐、リスナー)
概要
Spring Batchのステップの記述方法、条件分岐の記述方法のサンプルを見てみましょう。
目標
まず、以下のサンプルそれぞれの目標(ゴール)を示します。
①2つのtaskletの処理サンプルを見ます。
システムコマンドを実行するサンプルと、Javaクラスのメソッドを実行するサンプルです。
どちらもSpringBatchが用意している部品を使用するため、設定をするだけで実行できます。
②ステップを順番に処理し、失敗した場合は他のステップに分岐するサンプルを作成することを目標とします。
ただし、動作するものを作成するのではなく、設定ファイルの書き方のみを見ていくことを目的とします。
【ステップの動作】
step1
もし失敗したら、step2へ
それ以外は、step3へ
step2
処理終了後、step3へ
step3
終了
③また、リスナーを設定する別サンプルも見てみます。
リスナーは、イベントが発生したときに呼ばれるクラスです。
具体的には、ジョブの前後、ステップの前後、チャンクの読み込み時などをイベントで補足できます。
他にもいろいろなイベントを補足できますので、本家のリファレンスなどを見てみてください。
ここでは、ジョブの前後にログを出力するリスナーのサンプルを見てみます。
サンプル①(tasklet)
実際のサンプルは、以下のリンク先にありますので参照ください。
・3.1 システムコマンドを実行する方法
・3.2 ビジネスロジックなどを実行する方法
Taskletを自作する場合は、Taskletインターフェースをimplementsして処理を記述するだけです。
注意点としては、もしリスタート可能なTaskletを作成したい場合は、処理がエラーで途中で終了した場合でも
リスタートしたときに問題なく処理できるようになっていなければなりません。
以下の記事も参照ください。
サンプル②(条件分岐)
<ジョブ設定ファイル>
<!-- ジョブの処理 -->
<job id="job1" xmlns="http://www.springframework.org/schema/batch" incrementer="jobParametersIncrementer">
<step id="step1" parent="simpleStep" >
<next on="*" to="next3"/>
<next on="FAILED" to="next2"/>
</step>
<step id="step2" parent="mockStep" next="step3" />
<step id="step3" parent="mockStep" />
</job>
<bean id="jobParametersIncrementer" class="org.springframework.batch.core.launch.support.RunIdIncrementer" />
<bean id="simpleStep"
class="org.springframework.batch.core.step.item.SimpleStepFactoryBean" abstract="true">
<property name="jobRepository" ref="jobRepository" />
<property name="commitInterval" value="1" />
</bean>
ステップの動作は、順番に処理していくだけでしたら、stepタグのnext属性を使用します(例: next="step3")。
もし、条件分岐したい場合は、step1のようにnextタグなどを使用します。
【条件分岐用のタグ】
※条件分岐用のタグの属性について
on・・・ ExitStatusを記述します。*,?などのワイルドカードも使用できます。
to・・・ ステップ名を指定します。onで指定した値とマッチする場合に指定のステップに遷移します。
exit-code ・・・ジョブ処理を抜けるときのExitStatusを指定した値に変更できます。end,fail,stopなどのタグについてのみ使用可能です。
※on属性のマッチについて
on属性のマッチは、タグの順番は無関係で、一番マッチしていると思われるパターンが選択されます。
つまり、上記の例では*が先に記述されていますが、FAILEDが選択されます。
BatchStatusとExitStatusについて
BatchStatusとExitStatusは、自作しない限りはほとんど同じ値が設定されます。
試しにジョブを実行後にSpringBatchのDBのテーブルを見ていただければと思います。
違いは以下のようになります。
ExitStatus
BatchStatus
クラスです。内部に自由な文字列を設定できます。通常は自動で設定されますが、自作のTaskletやリスナーなどで自由な文字列を設定して返すようにもできます。
列挙型(Enum)です。種類はいくつかありますが、自由に変更はできません。
(種類は、COMPLETED、STARTING、STARTED、STOPPING、STOPPED、FAILED、ABANDONED、UNKNOWN)
ExitStatusを変更する方法
例えば、taskletを自作した場合、以下のようにExitStatusの値を自由に変更できます。
文字列には空白も使用可能です。
【ExitStatusの値を設定するサンプル】
@Override
public RepeatStatus execute(StepContribution paramStepContribution, ChunkContext paramChunkContext) throws Exception {
paramStepContribution.setExitStatus(new ExitStatus("SKIP"));
return RepeatStatus.FINISHED;
}
【リスナーによる変更方法】
また、リスナーを使用して値を変更することもできます。
StepExecutionListenerをimplementsして、ステップにリスナーを指定します。
コードは上記とほぼ同じですので省略します。afterStep()メソッドでreturnするオブジェクトを上記のように記述することになります。
Spring BatchのTipsも参照ください。
サンプル③(リスナー)
<ジョブ設定ファイル>
<job id="job" xmlns="http://www.springframework.org/schema/batch" incrementer="jobParametersIncrementer">
<listeners>
<listener ref="logListener" />
</listeners>
<step id="step1" parent="simpleStep" />
</job>
<!-- リスナー -->
<bean id="logListener" class="test.LogListener" />
ジョブのリスナーを設定するときはjobタグの直下に記述します。
もしステップのリスナーの場合は、stepタグの直下に同様の記述をします。
また、先述のサンプルでparentにしたSimpleStepFactoryBeanのプロパティで設定することもできます。
この場合は、parentで設定したステップすべてに同じリスナーが適用されます。
【補足】
リスナーはマージすることもできます。
ステップを作成しておき、その中にリスナーを設定しておきます。
そのステップをparentにして設定し、以下のようにmergeを有効にします。
<listeners merge="true">
<listener ref="listener2"/>
<listeners>
すると、もともと設定していたlistener1と、listener2の2つが適用されます。
これをうまく使うとメンテナンスが楽になるかと思います。
<リスナークラスサンプル: test.LogListener.java>
public class LogListener extends JobExecutionListenerSupport{
protected static final Log log = LogFactory.getLog(LogListener.class);
@Override
public void afterJob(JobExecution jobExecution) {
log.info("ジョブ終了");
}
public void beforeJob(JobExecution jobExecution) {
log.info("ジョブ開始");
};
}
リスナークラスは、interfaceを実装するだけです。
しかし、メソッドが多いinterfaceは、必要のないメソッドまで実装しなければならないため、面倒です。
そこで用意されたのが、JobExecutionListenerSupportです。
このクラスは、メソッドだけを実装しているサポートクラスです。(処理の記述はなし)
そうすると上記のように必要なメソッドだけを実装すればよくなります。
最後に
条件分岐の方法には、このほかにもdeciderタグを使用する方法があります。
Created Date: 2010/01/12