- 리스너는 배치 처리의 주요 순간들을 관찰하고, 각 시점에 필요한 동작을 정의할 수 있는 도구 - 배치 처리 중 발생하는 특정 이벤트를 감지하고 원하는 로직을 실행 할 수 있게 해줌 - Job 시작 전후, Step 실행 전후는 물론, 청크 단위 또는 아이템 단위 처리 시점까지 모든 과정에 개입할 수 있음 - 이를 통해 로깅, 모니터링, 에러 처리등 우리가...
public interface JobExecutionListener {
default void beforeJob(JobExecution jobExecution) { }
default void afterJob(JobExecution jobExecution) { }
}public interface StepExecutionListener extends StepListener {
default void beforeStep(StepExecution stepExecution) {}
@Nullable
default ExitStatus afterStep(StepExecution stepExecution) {
return null;
}
}public interface ChunkListener extends StepListener {
default void beforeChunk(ChunkContext context) { }
default void afterChunk(ChunkContext context) { }
default void afterChunkError(ChunkContext context) { }
}RepeatStatus.CONTINUABLE을 반환하면 execute() 실행이 반복되므로, 해당 범위로 동작public interface ItemReadListener<T> extends StepListener {
default void beforeRead() { }
default void afterRead() { }
default void onReadError(Exception ex) { }
}
public interface ItemProcessListener<T, S> extends StepListener {
default void beforeProcess(T item) { }
default void afterProcess(T item, @Nullable S result) { }
default void onProcessError(T item, Exception e) { }
}
public interface ItemWriteListener<S> extends StepListener {
default void beforeWrite(Chunk<? extends S> items) { }
default void afterWrite(Chunk<? extends S> items) { }
default void onWriteError(Exception exception, Chunk<? extends S> items) { }
}ItemReadListener.afterRead()는 ItemReader.read() 호출 후에 호출되지만, ItemReader.read() 메서드가 더 이상 읽을 데이터가 없어 null을 반환할 떄는 호출되지 않음ItemProcessListener.afterProcess는 ItemProcessor.process() 메서드가 null을 반환하더라도 호출된다.
null을 반환하는 것은 해당 데이터를 필터링하겠다는 의미ItemWriteListener.afterWrite()는 트랜잭션이 커밋되기 전, 그리고 ChunkListener.afterChunk()가 호출되기 전에 호출된다 +----------------+
| JobLauncher |
+----------------+
|
| beforeJob()
v
+-------------+
| Job |
+-------------+
|
| beforeStep()
v
+-------------+
| Step |
+-------------+
|
| beforeChunk()
v
==================================
|| Chunk #N ||
==================================
|
v
[ Item Processing ]
|
^
| afterChunk()
+-------------+
| Step |
+-------------+
|
| afterStep()
v
+-------------+
| Job |
+-------------++--------------------------------------------------+
| Chunk #N |
| |
| beforeRead() |
| | |
| v |
| read() --- 반복 --- |
| | |
| afterRead() |
| |
| beforeProcess() |
| | |
| v |
| process() --- 반복 --- |
| | |
| afterProcess() |
| |
| beforeWrite() |
| | |
| v |
| write() (List 단위) |
| | |
| afterWrite() |
| |
+--------------------------------------------------+@Bean
public ExecutionContextPromotionListener promotionListener() {
ExecutionContextPromotionListener listener = new ExecutionContextPromotionListener();
listener.setKeys(new String[]{"data"}); // data 키를 승격 대상으로 지정
return listener;
}