프레임워크(Framework)/Spring

[Spring Batch] 스프링 배치 Step 이해하기 - Spring boot 2.x

잇트루 2023. 7. 1. 13:27
반응형

Intro

스프링 배치의 도메인은 크게 두 가지로 나눌 수 있다.

  1. 배치를 특정 단계 또는 흐름에 따라 처리하고 구성하는 역할을 하는 도메인
    • Job, Step, Flow, Tasklet, …
  2. 배치의 단계마다 실행 정보나 상태 정보를 데이터베이스에 저장하기 위한 메타데이터 도메인
    • JobInstance, JobExecution, StepExecution, …

 

 

Step

Step 인터페이스는 Batch Job을 구성하는 독립적인 하나의 단계로서 실제 배치 처리를 정의하고 컨트롤하는 데 필요한 모든 정보를 가지고 있는 도메인 객체다. Step은 단순한 단일 태스크뿐만 아니라 입력과 처리, 출력과 관련된 복잡한 비즈니스 로직을 포함하는 모든 설정들을 담고 있다.

  • Step은 배치작업을 어떻게 구성하고 실행할 것인지에 대한 Job의 세부 작업을 Task 기반으로 설정하고 명세해 놓은 객체
  • 모든 Job은 하나 이상의 step으로 구성됨
  • Step은 인터페이스로 Spring Batch에서 기본적인 구현체들을 제공한다.

 

 

Step의 기본 구현체

TaskletStep

  • Step의 가장 기본이 되는 클래스로 Tasklet 타입의 구현체들을 제어한다.

 

PartitionStep

  • 멀티 스레드 방식으로 Step을 여러 개로 분리해서 실행한다.

 

JobStep

  • Step 내에서 Job을 실행한다.
  • Step 안에 존재하는 Job은 하나 이상의 step을 가진다.

 

FlowStep

  • Step 내에서 Flow를 실행한다.

 

이 외에도 몇 가지의 Step 기본 구현체가 존재한다. 스프링 배치에서 제공하는 Step의 기본 구현체들을 사용하는 것만으로도 대부분의 배치 Job을 구현할 수 있다.

 

 

Step 도메인 구조

Step

  • Step은 인터페이스로 StepExecution 도메인 객체를 인자로 받는 execute 메서드가 존재한다.
  • execute 메서드는 Step을 실행시키는 역할을 한다.
  • Step의 실행 결과에 대한 정보는 StepExecution에 저장된다.

 

AbstractStep

  • Step 인터페이스를 구현한 추상 클래스로 5가지의 속성을 가지고 있다.
  • name : Step의 이름
  • startLimit : Step의 실행 제한 횟수
  • allowStartIfComplete : Step의 실행이 완료된 후 재실행 여부(기본적으로 false)
  • stepExecutionListener : Step 이벤트 리스너
  • jobRepository : Step 메타데이터 저장소

 

각각의 기본 구현체

  • JobStep, TaskletStep, FlowStep, PartitionStep 등이 기본으로 구현되어 있으며, 각각의 구현체들은 서로 다른 속성들을 가진다.

 

 

Step의 실행 구조

  • Job이 실행되면 Job에 정의된 각각의 Step을 실행시킨다.
  • Step은 내부에 정의된 Tasklet을 실행시킨다.
  • Tasklet에는 실제 비즈니스 로직이 작성되어 있다.
  • Tasklet 인터페이스 안에는 ItemReader, ItemProcessor, ItemWriter와 같은 Chunk 기반 클래스를 포함할 수 있다.
  • Chunk 기반 클래스가 아닌 단일 Task로 구성할 수도 있다.

 

 

API 설정에 따른 각 Step 생성

TaskletStep

직접 생성한 Tasklet을 실행하는 경우

public Step step() {
    return stepBuilderFactory.get("step")
            .tasklet(myTasklet())
            .build();
}

 

ChunkOrientedTasklet을 실행하는 경우

public Step step() {
    return stepBuilderFactory.get("step")
            .<Member, Member>chunk(100)
            .reader(reader())
            .writer(writer())
            .build();
}

 

JobStep

Step에서 Job을 실행하는 경우

public Step step() {
    return stepBuilderFactory.get("step")
            .job(job())
            .launcher(jobLauncher)
            .parametersExtractor(jobParametersExtractor())
            .build();
}

 

FlowStep

public Step step() {
    return stepBuilderFactory.get("step")
            .flow(myFlow())
            .build();
}
반응형