TaskletStep
チャンク指向の処理は、Step
で処理する唯一の方法ではありません。Step
がストアドプロシージャコールで構成されている必要がある場合はどうなりますか ? 呼び出しを ItemReader
として実装し、プロシージャの終了後に null を返すことができます。ただし、何もしない ItemWriter
が必要になるため、そうするのは少し不自然です。Spring Batch は、このシナリオの TaskletStep
を提供します。
Tasklet
インターフェースには execute
という 1 つのメソッドがあり、TaskletStep
が RepeatStatus.FINISHED
を返すか例外をスローして失敗を通知するまで、このメソッドが繰り返し呼び出されます。Tasklet
への各呼び出しは、トランザクションにラップされます。Tasklet
の実装者は、ストアドプロシージャ、スクリプト、SQL 更新ステートメントを呼び出す場合があります。
Java
XML
Java で TaskletStep
を作成するには、ビルダーの tasklet
メソッドに渡される Bean が Tasklet
インターフェースを実装する必要があります。TaskletStep
をビルドするときは、chunk
の呼び出しを行わないでください。次の例は、単純なタスクレットを示しています。
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.tasklet(myTasklet(), transactionManager)
.build();
}
XML で TaskletStep
を作成するには、<tasklet/>
要素の ref
属性で、Tasklet
オブジェクトを定義する Bean を参照する必要があります。<tasklet/>
内では <chunk/>
要素を使用しないでください。次の例は、単純なタスクレットを示しています。
<step id="step1">
<tasklet ref="myTasklet"/>
</step>
StepListener インターフェースを実装している場合、TaskletStep は自動的にタスクレットを StepListener として登録します。 |
TaskletAdapter
ItemReader
および ItemWriter
インターフェースの他のアダプターと同様に、Tasklet
インターフェースには、既存のクラス TaskletAdapter
に適応できる実装が含まれています。これが役立つ例として、一連のレコードのフラグを更新するために使用される既存の DAO があります。Tasklet
インターフェース用のアダプターを作成しなくても、TaskletAdapter
を使用してこのクラスを呼び出すことができます。
Java
XML
次の例は、Java で TaskletAdapter
を定義する方法を示しています。
@Bean
public MethodInvokingTaskletAdapter myTasklet() {
MethodInvokingTaskletAdapter adapter = new MethodInvokingTaskletAdapter();
adapter.setTargetObject(fooDao());
adapter.setTargetMethod("updateFoo");
return adapter;
}
次の例は、TaskletAdapter
を XML で定義する方法を示しています。
<bean id="myTasklet" class="o.s.b.core.step.tasklet.MethodInvokingTaskletAdapter">
<property name="targetObject">
<bean class="org.mycompany.FooDao"/>
</property>
<property name="targetMethod" value="updateFoo" />
</bean>
Tasklet
の実装例
多くのバッチジョブには、さまざまなリソースをセットアップするためにメイン処理を開始する前に、または処理が完了してそれらのリソースをクリーンアップするために実行する必要があるステップが含まれています。ファイルを頻繁に使用するジョブの場合、特定のファイルを別の場所に正常にアップロードした後で、ローカルで削除する必要があることがよくあります。次の例 ( Spring Batch サンプルプロジェクト [GitHub] (英語) から取得) は、まさにそのような責任を持つ Tasklet
実装です。
public class FileDeletingTasklet implements Tasklet, InitializingBean {
private Resource directory;
public RepeatStatus execute(StepContribution contribution,
ChunkContext chunkContext) throws Exception {
File dir = directory.getFile();
Assert.state(dir.isDirectory(), "The resource must be a directory");
File[] files = dir.listFiles();
for (int i = 0; i < files.length; i++) {
boolean deleted = files[i].delete();
if (!deleted) {
throw new UnexpectedJobExecutionException("Could not delete file " +
files[i].getPath());
}
}
return RepeatStatus.FINISHED;
}
public void setDirectoryResource(Resource directory) {
this.directory = directory;
}
public void afterPropertiesSet() throws Exception {
Assert.state(directory != null, "Directory must be set");
}
}
上記の tasklet
実装は、指定されたディレクトリ内のすべてのファイルを削除します。execute
メソッドは 1 回だけ呼び出されることに注意してください。あとは step
から tasklet
を参照するだけです。
Java
XML
次の例は、Java で step
から tasklet
を参照する方法を示しています。
@Bean
public Job taskletJob(JobRepository jobRepository, Step deleteFilesInDir) {
return new JobBuilder("taskletJob", jobRepository)
.start(deleteFilesInDir)
.build();
}
@Bean
public Step deleteFilesInDir(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("deleteFilesInDir", jobRepository)
.tasklet(fileDeletingTasklet(), transactionManager)
.build();
}
@Bean
public FileDeletingTasklet fileDeletingTasklet() {
FileDeletingTasklet tasklet = new FileDeletingTasklet();
tasklet.setDirectoryResource(new FileSystemResource("target/test-outputs/test-dir"));
return tasklet;
}
次の例は、step
から tasklet
を XML で参照する方法を示しています。
<job id="taskletJob">
<step id="deleteFilesInDir">
<tasklet ref="fileDeletingTasklet"/>
</step>
</job>
<beans:bean id="fileDeletingTasklet"
class="org.springframework.batch.samples.tasklet.FileDeletingTasklet">
<beans:property name="directoryResource">
<beans:bean id="directory"
class="org.springframework.core.io.FileSystemResource">
<beans:constructor-arg value="target/test-outputs/test-dir" />
</beans:bean>
</beans:property>
</beans:bean>