条件分岐をさせるには? | Java Springの逆引きメモ

Java Springの逆引きメモ

JavaのSpring frameworkのメモを書いていきます!
初心者の勉強ノートなので間違いがあるかもしれませんが、何かヒントになることがあれば幸いです。

今までの記事では、処理をシーケンシャルに順番に処理する例のみを見てきました。

 

  ・Stepを使って処理を書くには?

  ・複数のStepをひとまとまりで扱うには?(flow)


ここでは、条件分岐する方法を見ていきましょう。




【サンプル1 (stepタグ内で条件分岐する方法)】

<job id="job2" xmlns="http://www.springframework.org/schema/batch "

 incrementer="jobParametersIncrementer">
   <step id="step.a">
     <tasklet >
       <chunk reader="fileItemReader1" writer="fileItemWriter1" />
     </tasklet>
     <next on="COMPLETED" to="step.b"/>
     <next on="*" to="step.c"/>
   </step>


   <step id="step.b">
     <tasklet >
       <chunk reader="fileItemReader2" writer="fileItemWriter2" />
     </tasklet>
   </step>

   <step id="step.c">
     <tasklet >
       <chunk reader="fileItemReader3" writer="fileItemWriter3" />
     </tasklet>
   </step>
</job>



説明:

step内でnextタグを使用します。

こうすると、stepを抜け出すときの状態をStepExecutionから取得して、一致する場合に次のstepに遷移します。

状態は文字列として保存されていますので、*のようなワイルドカードを使用することもできます。


上記の場合、

 COMPLETED のとき ⇒ step.bに遷移

 上記以外のとき ⇒ step.cに遷移


となります。


使用できる値は、ExitStatus を参考にしてみてください。

また使用できるタグはnextタグだけではありません。

以下のようなタグも使用可能です。

 

 next ・・・条件に合致する場合、次のstep処理に遷移します。

 fail ・・・条件に合致する場合、FAILED状態として処理を終了します。

 end ・・・条件に合致する場合、COMPLETED状態として終了します。restart不可です。

 stop ・・・条件に合致する場合、STOP状態として処理を終了します。restart可能です。


 ※endとfailについては、exit-code属性で、jobを抜けるときのステータスを変更することもできます。



【サンプル2 (リスナーを使用する方法)】

<job id="job2" xmlns="http://www.springframework.org/schema/batch "

 incrementer="jobParametersIncrementer">
   <step id="step.a">
     <tasklet >
       <chunk reader="fileItemReader1" writer="fileItemWriter1" />
       <listeners>
         <listener ref="skipCheckingListener"/>
       </listeners>
     </tasklet>
     <next on="COMPLETED WITH SKIPS" to="step.b"/>
     <next on="*" to="step.c"/>
   </step>


   <step id="step.b">
     <tasklet >
       <chunk reader="fileItemReader2" writer="fileItemWriter2" />
     </tasklet>
   </step>

   <step id="step.c">
     <tasklet >
       <chunk reader="fileItemReader3" writer="fileItemWriter3" />
     </tasklet>
   </step>
</job>


<bean id="skipCheckingListener" class="test.SkipCheckingListener" />



リスナークラスの例

public class SkipCheckingListener extends StepExecutionListenerSupport {

    public ExitStatus afterStep(StepExecution stepExecution) {
        String exitCode = stepExecution.getExitStatus().getExitCode();
        if (!exitCode.equals(ExitStatus.FAILED.getExitCode()) && 
              stepExecution.getSkipCount() > 0) {
            return new ExitStatus("COMPLETED WITH SKIPS");
        }
        else {
            return null;
        }
    }

}


【説明】

リスナーを使う方法だと、先ほどの例と違い、stepを抜け出すときの状態を表す文字列を自由に

決めることができます。

これでかなり自由度が上がると思います。


あとのnextタグなどの使用方法は全く同じです。




【サンプル3 (decisionを使用する方法)】

<job id="job" xmlns="http://www.springframework.org/schema/batch " >
  <step id="step1" parent="s1" next="decision" />

  <decision id="decision" decider="decider">
    <next on="FAILED" to="step2" />
    <next on="COMPLETED" to="step3" />
  </decision>

  <step id="step2" parent="s2" next="step3"/>
  <step id="step3" parent="s3" />
</job>

<bean id="decider" class="com.MyDecider"/>



Deciderクラスの例:

public class MyDecider implements JobExecutionDecider {
    public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
        if (someCondition) {
            return new FlowExecutionStatus("FAILED");
        }
        else {
            return FlowExecutionStatus.COMPLETED;
        }
    }
}



説明:

先ほどのサンプルでは、リスナーを使う方法もstep内に条件を記述していました。

しかし、deciderを使用すると条件分岐が1つのstepになっています。

これは条件分岐を使いまわしたい場合などには便利かと思います。




条件分岐については上記のものが主な方法かと思います。




参照:

・トップ

・SpringBatch機能について

・Stepを使って処理を書くには?

・複数のStepをひとまとまりで扱うには?(flow)

SpringBatch本家のドキュメント