spring-boot-starter-batch 를 의존성에 넣으면 Job이 하나만 있는 경우 별도 코드를 작성하지 않아도 애플리케이션 실행 시 applicationContext 에 등록된 Job이 자동 실행된다.
여러 개의 Job이 있을 경우 spring.batch.job.names (또는 spring.batch.job.name) 설정으로 어떤 Job을 실행할지 지정 가능하다.
@EnableBatchProcessing 은 Spring Batch 핵심 인프라(JobRepository, JobLauncher, JobExplorer, JobRegistry 등)를 자동으로 등록해주는데, 과거 Spring Boot 2.x에서는 이 어노테이션을 꼭 붙여야 Job 자동 실행이 가능했다.
public class PassBatchApplication {
private final JobBuilder jobBuilder;
private final StepBuilder stepBuilder;
public PassBatchApplication(JobBuilder jobBuilder, StepBuilder stepBuilder) {
this.jobBuilder = jobBuilder;
this.stepBuilder = stepBuilder;
}
@Bean
public Step passStep() {
return this.stepBuilder.get("passStep")
.tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("Excute PassStep");
return RepeatStatus.FINISHED;
}
}).build();
}
@Bean
public Job passJob() {
return this.jobBuilder.get("passJob")
.start(passStep())
.build();
}
Spring Boot 3.x 이후로는 자동 실행 정책이 조금 더 엄격해졌다. 아무 설정도 없으면 Job을 등록만 하고 실행하지 않는다. 여러 Job이 있을 때는 반드시 spring.batch.job.name=... 지정해야 실행된다.
따라서 JobLauncher 를 직접 쓰거나, spring.batch.job.name을 명시해야 Job 이 실행된다.
Spring Boot 3.x 이상에서는 대부분의 Batch 인프라를 Spring Boot Starter 가 자동으로 구성해 주기 때문에 @EnableBatchProcessing 을 꼭 붙이지 않아도 된다. 다만, 직접 JobBuilder 나 StepBuilder 를 사용할 때는 필요할 수 있다. (직접 Bean 등록 시 인프라가 없으면 예외 발생)
5에서는 JobBuilderFactory와 StepBuilderFactory가 삭제됐다.
@Configuration
public class PassBatchApplication {
@Bean
public Step passStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("passStep", jobRepository)
.tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("Execute PassStep");
return RepeatStatus.FINISHED;
}
}, transactionManager)
.build();
}
@Bean
public Job passJob(JobRepository jobRepository, Step passStep) {
return new JobBuilder("passJob", jobRepository)
.start(passStep)
.build();
}
}