Spring Batch에서 사용했던 Listener를 적어볼려고 합니다.
JobExecutionListener
JobListenerSupport
StepExecutionListenerSupport
제가 사용한 Listener
는 각 Job이 실행전, 후 Step이 실행전, 후를 기점으로 실행을 합니다.
해당 시점을 통해 어떤 Event
처리가 필요하다면은 유용하게 사용하실 수 있어요
public class TestJobListener implements JobExecutionListener {
private final String jobName;
public CustomJobListener(String jobName) {
this.jobName = jobName;
}
@Override
public void beforeJob(JobExecution jobExecution) {
logger.info("beforeJob Name: {} Started.", jobName);
}
@Override
public void afterJob(JobExecution jobExecution) {
logger.info("afterJob Name: {} End.", jobName);
}
}
@Bean
public Job testJob() {
return jobBuilderFactory
.get("testJob")
.incrementer(new RunIdIncrementer())
.listener(new TestJobListener("testJob"))
.start(testStep())
.build();
}
JobExecutionListener
를 상속받은 클래스를 구현 후
jobBuilderFactory
에서 상속 받은 클래스를 Listener
에 넣어주시면 되겠습니다
beforeJob
은 Job이 실행 전에 호출afterJob
은 Job이 실행 후에 호출위 2시점에 Event
를 넣을 수 있습니다.
public class TestJobListenerSupport extends JobListenerSupport {
@Override
public String getName() {
return this.getClass().getSimpleName();
}
@Override
public void jobToBeExecuted(JobExecutionContext jobExecutionContext) {
log.info("jobToBeExecuted Name: {} Started.", jobExecutionContext.getJobDetail().getKey());
}
@Override
public void jobExecutionVetoed(JobExecutionContext jobExecutionContext) {
log.info("jobExecutionVetoed Name: {} Started.", jobExecutionContext.getJobDetail().getKey());
}
@Override
public void jobWasExecuted(JobExecutionContext jobExecutionContext, JobExecutionException jobException) {
log.info("jobWasExecuted Name: {} Started.", jobExecutionContext.getJobDetail().getKey());
}
SchedulerFactoryBean factory = new SchedulerFactoryBean();
factory.setGlobalJobListeners(TestJobListenerSupport());
JobListenerSupport
를 상속받아 구현한 클래스를 구현 후
SchedulerFactoryBean
에 GlobalJobListeners
로 등록하면 됩니다.
jobToBeExecuted
Job이 호출되기 이전에 실행jobExecutionVetoed
는 vetoJobExecution
호출 시 실행 (중지 호출 시)jobWasExecuted
Job이 완료된 이후JDBC
를 사용한 다면 QRTZ_, Batch_
의 테이블 Update 이후 시점해당 Listener
는 Job이 호출 전, 후로 실행되기 때문에
처음 안내한 Listener
보다 이전에 실행되고, 이후에 실행하게 됩니다.
public class TestStepListenerSupport extends StepExecutionListenerSupport {
@Override
public void beforeStep(StepExecution stepExecution) {
log.info("beforeStep Name: {} Started.", stepExecution.getStepName());
}
@Override
public ExitStatus afterStep(StepExecution stepExecution) {
log.info("afterStep Name: {} Started.", stepExecution.getStepName());
}
}
public Step testStep() {
return stepBuilderFactory
.get("testSetp")
.<Test, Test>chunk(1000)
.reader(testReader())
.writer(testWriter())
.listener(new TestStepListenerSupport())
.build();
}
StepExecutionListenerSupport
상속받아 클래스 구현 후
stepBuilderFactory
에 listener
로 등록해주시면 됩니다.
beforeStep
Step이 실행되기 전afterStep
Step이 실행 된 후만약 한 Job에 여러 Step이 있을 경우 해당 Step 실행 전, 후 마다 Listenter
가 호출 되게 됩니다.
제가 설명드린 위 3의 Listener
를 모두 사용한다면 Log
에 찍히는 순서는
jobToBeExecuted Name: testJob Started.
beforeJob Name: testJob Started.
beforeStep Name: testStep Started.
afterStep Name: testStep Started.
afterJob Name: testJob End.
jobWasExecuted Name: testJob Started.
JobListenerSupport (jobToBeExecuted)
-> JobExecutionListener (beforeJob)
-> StepExecutionListenerSupport (beforeStep)
-> StepExecutionListenerSupport (afterStep)
-> JobExecutionListener (afterJob)
-> JobListenerSupport (jobWasExecuted)
위와 같은 순서로 처리되게 됩니다.
ChunkListener
ItemReadListener
ItemProcessListener
ItemWriteListener
SkipListener
Spring Batch Docs에서 확인해보시면 될 것 같아요