ジョブを実行する
少なくとも、バッチジョブを起動するには、起動する Job
と JobLauncher
の 2 つが必要です。どちらも同じコンテキストまたは異なるコンテキストに含めることができます。例: コマンドラインからジョブを起動すると、新しい JVM が各 Job
に対してインスタンス化されます。すべてのジョブには独自の JobLauncher
があります。ただし、HttpRequest
のスコープ内にある Web コンテナー内から実行する場合、通常、複数のリクエストがジョブを起動するために呼び出す 1 つの JobLauncher
(非同期ジョブ起動用に構成) があります。
コマンドラインからジョブを実行する
エンタープライズスケジューラからジョブを実行する場合は、コマンドラインが主要なインターフェースになります。これは、ほとんどのスケジューラ ( Quartz を除き、NativeJob
を使用しない場合) が、主にシェルスクリプトで開始されるオペレーティングシステムプロセスと直接連携するためです。Perl や Ruby などのシェルスクリプトや、Ant や Maven などのビルドツール以外にも、Java プロセスを起動する方法は多数あります。ただし、ほとんどの人はシェルスクリプトに精通しているため、この例ではシェルスクリプトに焦点を当てています。
CommandLineJobRunner
ジョブを起動するスクリプトは Java 仮想マシンを起動する必要があるため、プライマリエントリポイントとして機能する main
メソッドを持つクラスが必要です。Spring Batch は、この目的に役立つ実装を提供します: CommandLineJobRunner
。これは、アプリケーションをブートストラップする 1 つの方法にすぎないことに注意してください。Java プロセスを起動する方法は多数ありますが、このクラスを決定的なものと見なすべきではありません。CommandLineJobRunner
は次の 4 つのタスクを実行します。
適切な
ApplicationContext
をロードします。コマンドライン引数を
JobParameters
に解析します。引数に基づいて適切なジョブを見つけます。
アプリケーションコンテキストで提供される
JobLauncher
を使用して、ジョブを起動します。
これらのタスクはすべて、渡された引数のみで実行されます。次の表に、必要な引数を示します。
|
|
| 実行するジョブの名前。 |
これらの引数は、最初にパス、2 番目に名前を付けて渡す必要があります。これらの後のすべての引数は、ジョブパラメーターと見なされ、JobParameters
オブジェクトに変換され、name=value
の形式である必要があります。
Java
XML
次の例は、Java で定義されたジョブにジョブパラメーターとして渡された日付を示しています。
<bash$ java CommandLineJobRunner io.spring.EndOfDayJobConfiguration endOfDay schedule.date=2007-05-05,java.time.LocalDate
次の例は、ジョブパラメーターとして XML で定義されたジョブに渡される日付を示しています。
<bash$ java CommandLineJobRunner endOfDayJob.xml endOfDay schedule.date=2007-05-05,java.time.LocalDate
デフォルトでは、 次の例では、
カスタム |
Java
XML
ほとんどの場合、マニフェストを使用して jar で main
クラスを宣言することをお勧めします。ただし、簡単にするために、クラスを直接使用しました。この例では、バッチのドメイン言語の EndOfDay
例を使用します。最初の引数は io.spring.EndOfDayJobConfiguration
で、ジョブを含む構成クラスの完全修飾クラス名です。2 番目の引数 endOfDay
はジョブ名を表します。最後の引数 schedule.date=2007-05-05,java.time.LocalDate
は、java.time.LocalDate
型の JobParameter
オブジェクトに変換されます。
次の例は、Java での endOfDay
の構成例を示しています。
@Configuration
@EnableBatchProcessing
public class EndOfDayJobConfiguration {
@Bean
public Job endOfDay(JobRepository jobRepository, Step step1) {
return new JobBuilder("endOfDay", jobRepository)
.start(step1)
.build();
}
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.tasklet((contribution, chunkContext) -> null, transactionManager)
.build();
}
}
ほとんどの場合、マニフェストを使用して jar で main
クラスを宣言する必要があります。ただし、簡単にするために、クラスを直接使用しました。この例では、バッチのドメイン言語の EndOfDay
例を使用します。最初の引数は endOfDayJob.xml
で、これは Job
を含む Spring ApplicationContext です。2 番目の引数 endOfDay,
はジョブ名を表します。最後の引数 schedule.date=2007-05-05,java.time.LocalDate
は、java.time.LocalDate
型の JobParameter
オブジェクトに変換されます。
次の例は、XML での endOfDay
の構成例を示しています。
<job id="endOfDay">
<step id="step1" parent="simpleStep" />
</job>
<!-- Launcher details removed for clarity -->
<beans:bean id="jobLauncher"
class="org.springframework.batch.core.launch.support.TaskExecutorJobLauncher" />
上記の例は、一般に Spring Batch でバッチジョブを実行するための要件が他にもたくさんあるため、非常に単純化されていますが、CommandLineJobRunner
の 2 つの主要な要件である Job
と JobLauncher
を示すのに役立ちます。
終了コード
コマンドラインからバッチジョブを起動する場合、エンタープライズスケジューラがよく使用されます。ほとんどのスケジューラはかなり馬鹿げており、プロセスレベルでしか機能しません。これは、一部のオペレーティングシステムプロセス (呼び出したシェルスクリプトなど) しか認識していないことを意味します。このシナリオでは、ジョブの成功または失敗についてスケジューラに返信する唯一の方法は、リターンコードを使用することです。リターンコードは、実行の結果を示すためにプロセスによってスケジューラに返される番号です。最も単純なケースでは、0 は成功、1 は失敗です。ただし、「ジョブ A が 4 を返す場合はジョブ B を開始し、5 を返す場合はジョブ C を開始する」など、より複雑なシナリオが存在する場合もあります。この型の動作はスケジューラレベルで構成されますが、Spring Batch などの処理フレームワークが特定のバッチジョブの終了コードの数値表現を返す方法を提供することが重要です。Spring Batch では、これは ExitStatus
内にカプセル化されます。これについては、第 5 章で詳しく説明します。終了コードについて説明する目的で知っておくべき唯一の重要なことは、ExitStatus
にはフレームワークによって設定される終了コードプロパティがあることです (または開発者) であり、JobLauncher
から返される JobExecution
の一部として返されます。CommandLineJobRunner
は、ExitCodeMapper
インターフェースを使用して、この文字列値を数値に変換します。
public interface ExitCodeMapper {
public int intValue(String exitCode);
}
ExitCodeMapper
の本質的な契約は、文字列の終了コードを指定すると、数値表現が返されるということです。ジョブランナーが使用するデフォルトの実装は SimpleJvmExitCodeMapper
で、完了の場合は 0、一般的なエラーの場合は 1、指定されたコンテキストで Job
が見つからないなどのジョブランナーのエラーの場合は 2 を返します。上記の 3 つの値よりも複雑なものが必要な場合は、ExitCodeMapper
インターフェースのカスタム実装を提供する必要があります。CommandLineJobRunner
は ApplicationContext
を作成するクラスであるため、「一緒に接続」することはできないため、上書きする必要がある値はすべてオートワイヤーする必要があります。これは、ExitCodeMapper
の実装が BeanFactory
内で見つかった場合、コンテキストが作成された後にランナーに注入されることを意味します。独自の ExitCodeMapper
を提供するために行う必要があるのは、実装をルートレベル Bean として宣言し、それがランナーによってロードされる ApplicationContext
の一部であることを確認することだけです。
Web コンテナー内からのジョブの実行
以前は、前述のように、オフライン処理 (バッチジョブなど) はコマンドラインから起動されていました。ただし、HttpRequest
からの起動がより適切なオプションである場合が多くあります。このようなユースケースの多くには、レポート、アドホックジョブの実行、および Web アプリケーションのサポートが含まれます。バッチジョブは (定義上) 長時間実行されるため、最も重要な関心事は、ジョブを非同期で起動することです。
この場合のコントローラーは Spring MVC コントローラーです。Spring MVC の詳細については、Spring Framework リファレンスガイドを参照してください。コントローラーは、非同期で起動するように構成された JobLauncher
を使用して Job
を起動し、すぐに JobExecution
を返します。Job
はまだ実行されている可能性があります。ただし、この非ブロック動作により、コントローラーはすぐに戻ることができます。これは、HttpRequest
を処理するときに必要です。次のリストは例を示しています。
@Controller
public class JobLauncherController {
@Autowired
JobLauncher jobLauncher;
@Autowired
Job job;
@RequestMapping("/jobLauncher.html")
public void handle() throws Exception{
jobLauncher.run(job, new JobParameters());
}
}