背景
An ItemReader, ItemWriter or ItemProcessor that itself implements one of the StepListener interfaces is registered automatically with the Step if using the namespace element or one of the the *StepFactoryBean factories.
https://docs.spring.io/spring-batch/4.1.x/reference/html/step.html#interceptingStepExecution より抜粋
ItemReader
とかの実装クラスにStepExecutionListener
とかのリスナーを実装しとくと、(少なくともspring-bootと一緒にspring-batch動かす分には)そのリスナーも自動登録する、とのこと。とりあえずやってみる。
というか、知らなくてちょっとびっくりしたんでメモ書きを残す。
ソースコード
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
ItemReader + StepExecutionListener
適当なchunk処理をつくる。
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.StepExecutionListener;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.NonTransientResourceException;
import org.springframework.batch.item.ParseException;
import org.springframework.batch.item.UnexpectedInputException;
import org.springframework.stereotype.Component;
@Component
public class SampleChunk implements ItemReader<String>, ItemWriter<String>, StepExecutionListener {
@Override
public void write(List<? extends String> items) throws Exception {
items.forEach(s -> System.out.println(s));
}
int i=0;
@Override
public String read() throws Exception, UnexpectedInputException, ParseException, NonTransientResourceException {
if (i<5) {
i++;
return i + "";
}
return null;
}
@Override
public void beforeStep(StepExecution stepExecution) {
System.out.println("beforeStep");
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
System.out.println("afterStep");
return stepExecution.getExitStatus();
}
}
step定義
適当なstep定義をつくる。
@Autowired
SampleChunk r2;
@Bean("chunkstep1")
public Step step1() {
StepExecutionListener s = new SampleChunk();
return stepBuilderFactory
.get("step1")
.<String, String>chunk(1)
.reader(r2)
.writer(r2)
.build();//.listener(s)
}
実行
beforeStep
1
2
3
4
5
afterStep
確かにリスナーも登録されている。
listenerでも登録
以下のようにlistener
でもリスナーを登録してみる。
@Bean("chunkstep1")
public Step step1() {
StepExecutionListener s = new SampleChunk();
return stepBuilderFactory
.get("step1")
.<String, String>chunk(1)
.reader(r2)
.writer(r2)
.listener(s)
.build();
}
beforeStep
beforeStep
1
2
3
4
5
afterStep
afterStep
これだと二重に出る。