개발놀이터

스프링 배치 도메인의 이해 : Job 본문

Spring/Spring Batch

스프링 배치 도메인의 이해 : Job

마늘냄새폴폴 2022. 9. 20. 13:41

본 포스팅은 인프런의 정수원님의 스프링 배치 강의를 듣고 정리한 포스팅입니다. 더 자세한 내용은 강의를 참고해주세요. 

 

 

Job

기본 개념

배치 계층 구조에서 가장 상위에 있는 개념으로 하나의 배치 작업 자체를 의미합니다. 이는 API 서버의 접속 로그 데이터를 통계로 서버로 옮기는 배치인 Job 자체를 의미합니다. 

 

Job Configuration을 통해 생성되는 객체 단위로서 배치작업을 어떻게 구성하고 실행할 것인지 전체적으로 설정하고 명세해 놓은 객체입니다. 

 

배치 Job을 구성하기 위한 최상위 인터페이스이며 스프링 배치가 기본 구현체를 제공해줍니다. 여러 Step을 포함하고 있는 컨테이너로서 번드시 한개 이상의 Step으로 구성해야 합니다. 

 

 

기본 구현체

  • SimpleJob
    • 순차적으로 Step을 실행시키는 Job
    • 모든 Job에서 유용하게 사용할 수 있는 표준 기능을 갖고 있음
  • FlowJob
    • 특정한 조건과 흐름에 따라 Step을 구성하여 실행시키는 Job
    • Flow 객체를 실행시켜 작업을 진행함

 

이제 간단한 Job을 만들어서 Job이 어떻게 구동되는지 흐름을 한번 파악해보도록 하겠습니다. 

 

우선 Job을 만듭니다.

 

package io.sprintbatch.springbatchlecture;

import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepContribution;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@RequiredArgsConstructor
public class JobConfiguration {

    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job job() {
        jobBuilderFactory.get("job")
                .start(step1())
                .next(step2())
                .build()
    }

    @Bean
    public Step step1() {
        return stepBuilderFactory.get("step1")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("step1 was executed");

                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }
    
    @Bean
    public Step step2() {
        return stepBuilderFactory.get("step2")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution stepContribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("step2 was executed");
                        
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }
}

 

그리고 디버그모드로 흐름을 천천히 파악해보도록 하겠습나다. 

 

 

이렇게 브레이크 포인트를 잡아놓고 따라가보도록 하겠습니다. 

 

먼저 이동하는 곳은 SimpleJobBuilder 입니다. 이곳에서 JobBuilder는 Step들을 List로 관리합니다. 

 

 

위의 JobBuilderFactory로 start라는 메서드를 호출했습니다. 이 start라는 메서드는 Step을 Argument로 받아 리스트에 하나씩 저장합니다. 

 

 

그 다음 next라는 메서드를 호출해서 마찬가지로 List에 Step을 하나씩 담습니다.

 

이렇게 되면 최종적으로 List에는 두개의 Step이 담겨져있게 됩니다. 

 

 

이제 build라는 메서드를 호출하게 되면 Job의 구현체 중 SimpleJob을 호출하게 됩니다. 그렇게 되면 SimpleJobBuilder로 이동해서 

 

SimpleJob 객체를 만들고 아까 Step을 담아두었던 List를 setSteps를 통해 Job에 세팅합니다. 

 

 

이렇게해서 Job에 대한 세팅이 완료되었습니다. 이후에 Job은 bean으로 등록될 때 자동으로 실행되게 되어있습니다. 바로 BatchAutoConfiguration 클래스에서 JobLauncherApplicationRunner를 이용해서 실행됩니다. 

 

 

jobLauncher는 run 메서드를 이용해 job과 jobParameter를 가지고 Job을 실행시킵니다. 

 

실행이 되고 나면 AbstractJob 으로 가서 doExecute를 실행하게 됩니다. 

 

 

이제 doExecute 메서드를 실행함으로 인해서 드디어 SimpleJob 클래스로 넘어가게 됩니다. 

 

여기서 StepExecution을 만들고 StepHandler 가 Step을 실행합니다. Step을 실행하게 되면 Step안에 존재하는 tasklet이 실행됩니다. 

 

여기까지 Job이 설정되고 실행되는 사이클을 살펴봤습니다. 

 

다음 포스팅에서는 JobInstance 에 대해서 알아보도록 하겠습니다. 긴 글 읽어주셔서 감사합니다.