[Spring Batch] cli 실행 - JobLauncherApplicationRunner
SpringBoot 안쓰는 경우 - CommandLineJobRunner
- 공식 docs 참고 - https://docs.spring.io/spring-batch/docs/4.3.6/reference/html/job.html#runningAJob
- https://kwonnam.pe.kr/wiki/springframework/batch/commandlinejobrunner
SpringBoot 쓰는 경우 - yml 이용한 세팅
- SpringBoot 쓰는데 CommandLineJobRunner를 쓰게 되면 프로그램 실행 인입점이 main이 아니라 CommandLineJobRunner가 된다. >>> SpringBoot Auto-config가 제대로 적용되지 않는다. 해서 부트에서는 아래 구성요소들을 이용해야 한다.
- BatchAutoConfiguration.html
- JobLauncherCommandLineRunner.html (Spring Boot 2)
- JobLauncherApplicationRunner.html (Spring Boot 3)
- 여러 job들을 ,로 명시해서 실행하는 기능은 제거된 듯. https://github.com/spring-projects/spring-boot/issues/25373
- https://jojoldu.tistory.com/328
- https://kwonnam.pe.kr/wiki/springframework/springboot/batch
public class BatchAutoConfiguration {
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true)
public JobLauncherApplicationRunner jobLauncherApplicationRunner(JobLauncher jobLauncher, JobExplorer jobExplorer,
JobRepository jobRepository, BatchProperties properties) {
JobLauncherApplicationRunner runner = new JobLauncherApplicationRunner(jobLauncher, jobExplorer, jobRepository);
String jobNames = properties.getJob().getName();
if (StringUtils.hasText(jobNames)) {
runner.setJobName(jobNames);
}
return runner;
}
- SpringBoot 3 기준, BatchAutoConfiguration에서 JobLauncherApplicationRunner를 Bean으로 등록해준다.
- SpringBoot 2 까지는 spring.batch.job.enabled=false로 만들어야 jobName을 누락하는 경우 전체 job 실행되지 않았던 것 같은데, SpringBoot 3 부터는 spring.batch.job.enabled=true여도 jobName 누락하더라도 전체 job이 실행되지 않는다. 옵션을 true로 놓아도 무방하다.
Caused by: java.lang.IllegalArgumentException: Job name must be specified in case of multiple jobs
at org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner.validate
어째서인지 BatchAutoConfiguration으로 자동으로 Bean이 생성되지 않는다.
원인은 ? Spring Boot 3 부터 @EnableBatchProcessing를 붙이면 auto-config 기능이 비활성화 되기 때문 !
Spring Boot 2와 정반대로, 애너테이션을 없애야 auto-config가 적용되어 Bean이 생성된다.
JobLauncherApplicationRunner에 알 수 없는 job name을 넘겨도 배치가 실패하지 않는다.
따라서 별도 PostConstructor를 이용해 검사하거나, 아예 JobLauncherApplicationRunner 빈 자체를 직접 생성하면서 검사하는 것이 좋아보인다. 요구사항을 만족하는 빈을 직접 생성하기로 했다.
직접 JobLauncherApplicationRunner Bean 생성
요구사항
JobParameter 목록에 현재시각을 자동으로 추가해주어야 한다.- 생각해보니 이 요구사항은 제거해도 될 것 같다.
- 배치에서 사용할 기준 시간이 필요해서 받는거라면, 이를 꼭 JobParameter로 받을 필요는 없다.
- 같은 파라미터로 재수행 불가하기 때문에 파라미터 바꿔주기 위해 받는거라면, 이는 allowStartIfComplete 설정이나, Increment를 넣어주면 된다.
- cli에서 key1=value1 key2=value2 형식으로 잡파라미터 받을 수 있어야 한다.
- 알 수 없는 job name이 들어왔을 때, 실패해야 한다. (ExitCode도 비정상 반환)
- 배치 중간에 실패했을 때, 애플리케이션 ExitCode를 비정상으로 반환해야 한다.
@EnableConfigurationProperties(BatchProperties::class)
@Configuration
class JobLauncherApplicationRunnerConfig {
@Bean
fun jobLauncherApplicationRunner(
jobLauncher: JobLauncher, jobExplorer: JobExplorer, jobRepository: JobRepository,
properties: BatchProperties, jobs: Collection<Job>
): JobLauncherApplicationRunner {
val runner = JobLauncherApplicationRunner(jobLauncher, jobExplorer, jobRepository)
val jobName = properties.job.name
if (!jobs.map { it.name }.contains(jobName)) {
logger.error { "### job Bean [$jobName] 찾을 수 없음" }
throw IllegalArgumentException("### job Bean [$jobName] 찾을 수 없음")
}
runner.setJobName(jobName)
return runner
}
}
@SpringBootApplication
class MyBatchApplication
fun main(args: Array<String>) {
val applicationContext = runApplication<MyBatchApplication>(*args)
val exitCode = SpringApplication.exit(applicationContext)
exitProcess(exitCode)
}
위와 같이 세팅하면 요구사항을 만족 할 수 있다.
contribution
이런 기능은 아예 JobLauncherApplicationRunner에서 제공해주는게 좋아보여 이슈를 올렸는데.
https://github.com/spring-projects/spring-boot/issues/35940
갑자기 나타난 인도인이 PR을 먼저 올리면서 그 친구가 담당해서 처리하게 되었다...;; (PR을 보니 contribution이 무지 하고싶었나봄... Author에 자기 이름도 넣어두고. 그래그래 이해한다 ㅎ)
아무튼 잘 처리해 주시길...
Test시에는 어떻게?
https://www.baeldung.com/spring-junit-prevent-runner-beans-testing-execution
'Java Stack > Spring Batch' 카테고리의 다른 글
전문 해석기 배치 LineMapper - BeanWrapperFieldSetMapper와 RecordFieldSetMapper의 차이 (0) | 2023.06.29 |
---|---|
전문 해석기 배치 LineMapper - PatternMatchingCompositeLineMapper (0) | 2023.06.22 |
Spring Boot 3 에서 변경된 부분 (Batch) (0) | 2023.06.14 |
Spring Batch Multi-threaded Step 사용 시 chunk 구성에 대한 오해 (0) | 2022.12.16 |
[Spring Batch] 병렬 처리 방법 모음 (0) | 2022.09.15 |