Spring Batch : Listener

    이 글은 인프런 정수원님의 강의를 보고 복습하며 정리한 글입니다.

    Listener

    리스너는 배치 흐름 중에 Job, Step, Chunk 실행 전후에 어떤 일을 하도록 하는 Interceptor 개념의 클래스다. 스프링 MVC의 Interceptor가 실제로 HandlerAdapater 호출 전후로 Interceptor가 호출되는 것처럼 Job, Step, Chunk 전후로 오버라이딩된 메서드가 호출된다. 

    주로 각 단계별로 로그 기록을 남기거나, 진행된 시간, 실행 상태 정보들을 참조 및 조회하는데 도움이 된다. SpringBatch에서 Listener를 사용하기 위해서는 API 리스너에 리스너를 지정해주면 된다. 

     

    Listener 종류

    • Job
      • JobExecutionListener : Job 실행 전/후 리스너 설정 가능
    • Step
      • StepExecutionListener : Step 실행 전/후 리스너 설정 가능
      • ChunkListener : Chunk(Tasklet) 실행 전/후 리스너 설정 가능, 오류 시점.
      • ItemReaderListener : ItemReader 실행 전/후, 오류 시점. Item이 null일 경우 호출 안됨.
      • ItemWriterListener : ItermWriter 실행 전/후, 오류 시점. Item이 null일 경우 호출 안됨.
      • ItemProcessorListener : ItemProcessor 실행 전/후, 오류 시점. Item이 null일 경우 호출 안됨. 
    • SkipListener
      • 읽기 / 쓰기 / 처리 Skip 실행 시점, Item 처리가 Skip 될 경우 Skip된 Item을 추적함. (ItemReader/Processor/Writer에 예외가 발생했을 때 Skip 기능이 동작하고, 이 때 적용)
    • RetryListener
      • Retry 시작, 종료, 에러 시점에 적용 가능

     

    Listener를 사용하는 방법

    1. 어노테이션 기반 리스너 클래스 구현
    2. 리스너 인터페이스 구현

    리스너를 사용하는 방법은 위 두 가지 방법이 있다. 위의 방법 중 편한 방법을 선택해서 하면 된다. 한 가지 알아두어야 할 부분은 Listener API를 살펴보면 Object 타입의 리스너를 원할 때가 있다. 이 때는 반드시 어노테이션 기반의 리스너를 사용해야한다. 

    @Component
    public class CustomJobListener {
    
        @BeforeJob
        public void beforeJob(JobExecution jobExecution) {
            System.out.println("jobExecution = " + jobExecution);
            System.out.println("before Job Executed");
        }
    
        @AfterJob
        public void afterJob(JobExecution jobExecution) {
            System.out.println("jobExecution = " + jobExecution);
            System.out.println("After Job Executed");
        }
    }

    어노테이션 기반의 리스너는 다음과 같이 구현할 수 있다. 핵심은 @BeforeJob / @AfterJob으로 어떤 객체의 어느 시점에 실행할지를 정해준다. 그리고 이 클래스를 Bean으로 등록해서 JobBuilder 혹은 StepBuilder의 Listener API에 DI를 해주면 정상적으로 동작한다. 

    위 어노테이션 실행 로그

    또한 주의해서 봐둬야 할 부분은 자동으로 파라메터 바인딩을 해준다는 것이다. 위의 클래스는 철저하게 Custom Class인데도 불구하고 JobExecution 같은 인자를 받을 수 있다. 당연한 이야기겠지만 JobListener이기 때문에 JobExecution을 받을 수 있는거고, StepExecution이 받을 수 없다. 따라서 어떤 어노테이션을 쓰느냐에 따라 DI 되는 파라메터가 달라지는 것을 인지해야한다. 

     

    인터페이스 방식

    인터페이스 방식은 위와 같이 구현한다. 인터페이스를 구현하고 등록해주면, Job이나 Step등에서 before / after 메서드를 호출해주는 방식으로 동작한다. 

     

    각 Listener의 동작 위치

    Spring Batch가 제공하는 Listener는 다음과 같다. 잘 알아두면 좋을 것 같은 부분은 Listener끼리 파라미터 바인딩 한 것을 주고 받을 수 있으니, 그것을 바탕으로 어떤 구간에서 걸리는 시간이 얼마다를 정확하게 알 수 있을 것 같다. 위의 동작 방식을 외우기 보다는, 전후로는 이렇게 동작할 수 있구나를 이해하면 될 것 같다.

     

    댓글

    Designed by JB FACTORY