Spring Batch 5에서 main 메서드를 실행했는데 Job이 자동으로 실행되지 않는다.

Kyle·2023년 10월 15일
1

Spring Batch

목록 보기
1/3
post-thumbnail

문제 상황


스프링 부트 3점대 버전을 사용하려면 스프링은 6점대, 스프링 배치는 5점대 버전을 사용해야 합니다.

스프링 버전이 v4에서 v5로 올라가면서 몇가지 변화들이 생겼습니다.

그 중 하나가 그동안 스프리 배치의 인프라스터럭처 빈들을 자동으로 설정해주던 @EnableBatchProcessing 애너테이션과 관련된 내용입니다.

기존에는 아래와 같이 잡을 설정하면 main 메서드 실행시 Job이 실행되었습니다.

@Configuration
@EnableBatchProcessing
class MyBatchConfig {  
  
    @Bean  
    fun job(jobRepository: JobRepository, step1: Step): Job {  
        return JobBuilder("myJob", jobRepository)  
            .start(step1)  
            .build()  
    }  
  
    @Bean  
    fun step(jobRepository: JobRepository, transactionManager: JdbcTransactionManager): Step {  
        return StepBuilder("step1", jobRepository)  
            .tasklet(Tasklet { contribution, chunkContext ->  
                             println("Hello World!")  
                RepeatStatus.FINISHED  
            }, transactionManager)  
            .build()  
    }  
}
@SpringBootApplication  
class SpringBatchStudyApplication  
  
fun main(args: Array<String>) {  
    runApplication<SpringBatchStudyApplication>(*args)  
}

하지만 위와 같이 단순히 스프링을 부트스트랩하기만 하고 Job은 실행되지 않습니다.

Spring boot의 batch 관련 자동 구성 클래스 살펴보기


스프링 부트가 자동 구성해주는 부분에서 변화가 있을 것이라 생각해서 코드를 살펴보기로 했습니다.

org.springframework.boot.autoconfigure.AutoConfiguration.imports 파일을 살펴봅니다.
(@EnableAutoConfiguration 애너테이션에 의해 제공되는 기능입니다.)

batch 라는 키워드로 검색해서 BatchAutoConfiguration 설정 클래스를 찾았습니다.

BatchAutoConfiguration

org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration 패키지에 속해 있는 설정 클래스입니다.

spring batch에서 제공하는 클래스가 아닌 boot 에서 제공해주는 클래스라는 점에 주목해야 합니다.

주석에 원하는 내용이 나와있습니다.
하나의 잡이 애플리케이션 컨텍스트에 존재하면 시작시에 실행된다고 되어 있습니다.
이 설정 클래스가 기존에는 자동 구성되었을 것입니다. 조건을 자세히 살펴봅시다.

@ConditionalOnMissingBean(value = DefaultBatchConfiguration.class, annotation = EnableBatchProcessing.class)

DefaultBatchConfiguration@EnableBatchProcessing을 대신하는 스프링 배치 v5에서 추가된 기능입니다.
역시 인프라스트럭처 빈들을 자동 설정해주는 기능을 갖고 있습니다.

BatchAutoConfiguration, 이 스프링 부트의 자동 구성 클래스는 위 두가지 빈이 모두 없어야 작동하게 됩니다.

그러면 JobLauncherApplicationRunner 빈이 등록되고 자동으로 Job이 실행되게 됩니다.
물론 JobLauncherApplicationRunner 빈을 수동으로 등록해줘도 자동 실행이 가능합니다.

같은 내용의 질문을 stack overflow에서도 찾을 수 있습니다. spring batch 개발하신 분이 의도된 부분이라도 답글을 달아 주셨습니다.

자동 구성되는 DefaultBatchConfiguration

BatchAutoConfiguration 클래스를 조금 더 살펴보겠습니다.

아래로 좀만 내려가면 DefaultBatchConfiguration 클래스를 확장한 설정 클래스가 결국 빈으로 등록됨을 알 수 있습니다.
다시 말해 @EnableBatchProcessing 이나 DefaultBatchConfiguration 을 수동으로 작성하지 않으면 DefaultBatchConfiguration을 스프링 부트가 자동으로 구성해주게 됩니다.

DefaultBatchConfiguration은 아래와 같은 인프라스트럭처 빈들을 자동으로 등록하여 줍니다.

  • JobRepository
  • JobLauncher
  • JobExplorer
  • JobRegistry
  • JobOperator

보시다시피 이 클래스는 @EnableBatchProcessing 애너테이션을 프로그래밍 방식으로 대체하기 위해 만들어졌습니다.

이 설정 클래스를 사용하여 커스텀 빈을 설정할 수도 있습니다.
커스텀하기 원하는 설정의 getter를 오버라이딩 해주면 됩니다.

@Configuration
class MyJobConfiguration extends DefaultBatchConfiguration {

	@Bean
	public Job job(JobRepository jobRepository) {
		return new JobBuilder("job", jobRepository)
				// define job flow as needed
				.build();
	}

	@Override
	protected Charset getCharset() {
		return StandardCharsets.ISO_8859_1;
	}
}

위 예에서는 job repository 및 job explorer에서 사용되는 기본 문자 인코딩을 재정의하는 방법을 보여줍니다.

What’s New in Spring Batch 5.0 에 자세한 내용이 나와있습니다.

해결


위에서 확인한 내용을 눈으로 확인해보겠습니다.

@Configuration  
class MyBatchConfig {  
  
    @Bean  
    fun job(jobRepository: JobRepository, step1: Step): Job {  
        return JobBuilder("myJob", jobRepository)  
            .start(step1)  
            .build()  
    }  
  
    @Bean  
    fun step(jobRepository: JobRepository, transactionManager: JdbcTransactionManager): Step {  
        return StepBuilder("step1", jobRepository)  
            .tasklet(Tasklet { contribution, chunkContext ->  
                             println("Hello World!")  
                RepeatStatus.FINISHED  
            }, transactionManager)  
            .build()  
    }  
}

@EnableBatchProcessing 애너테이션을 제거해주었습니다.

다시 메인 메서드를 통해 애플리케이션을 실행시켜 보겠습니다.

반가운 Hello World! 가 정상적으로 출력됩니다.

스프링 배치 v5 부터 변경된 인프라스트럭처 자동 구성에 대해 알아보았습니다.
이대로 배치 애플리케이션을 구성하진 않겠지만, 스프링 배치 infrastructure 레이어에 대해 이해하는 데 중요한 부분이라고 생각하여 정리해 보았습니다.

0개의 댓글