Step은 독립적이고 순차적으로 배치 처리를 수행한다. 트랜잭션은 스텝 내에서 이루어진다. 스텝은 서로 독립되도록 의도적으로 설계됐다. 개발자는 필요에 따라 자유롭게 잡을 구조화할 수 있다.
실제 배치 처리를 정의하고 컨트롤하는데 필요한 모든 정보를 갖고 있는 도메인 객체.
단순한 단일 task 뿐 아니라 입력과 처리, 그리고 출력과 관련된 복잡한 비즈니스 로직을 포함하는 모든 설정들을 담고 있다.
배치 작업을 어떻게 구성하고 실행할 것인지 Job의 세부 작업을 Task 기반으로 설정하고 명세해놓은 객체.
모든 Job은 하나 이상의 Step으로 구성.
2) 기본 구현체
TaskletStep
가장 기본이 되는 클래스로서 Tasklet 타입의 구현체들을 제어한다.
TaskletStep을 생성하는 기본 빌더 클래스TaskletStep을 생성하며 내부적으로 청크기반의 작업을 처리하는 ChunkOrientedTasklet 클래스를 생성한다.
PartitionStep
멀티 스레드 방식으로 Step을 여러 개로 분리해서 실행한다.
JobStep
Step 내에서 Job을 실행하도록 한다.
Step이 Job의 하위 개념이지만, Step 안에서 job을 구성할수있다. Step -> job -> step -> job -> step, ...
FlowStep
Step 내에서 Flow를 실행하도록 한다.
3) 구조
실습
실습 1)
@RequiredArgsConstructor
@Configuration
public class StepConfiguration {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Bean
public Job BatchJob() {
return this.jobBuilderFactory.get("Job")
.start(step1())
.next(step2())
.next(step3())
.build();
}
@Bean
public Step step1() {
return stepBuilderFactory.get("step1")
.tasklet(new Tasklet() { // 편의상 익명클래스를 사용했지만 클래스로 만들어도 된다. step3 참고
// StepBuilder.tasklet -> TaskletStepBuilder을 반환한다.
// TaskletStepBuilder : Tasklet을 만들어주는 빌더클래스.
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("step1 has executed");
return RepeatStatus.FINISHED;
}
})
.build(); // AbstractTaskletStepBuilder.build -> TaskletStep을 반환한다.
}
@Bean
public Step step2() { // 람다로 구성
return stepBuilderFactory.get("step2")
.tasklet((contribution, chunkContext) -> {
System.out.println("step2 has executed");
return RepeatStatus.FINISHED;
})
.build();
}
@Bean
public Step step3() {
return stepBuilderFactory.get("step3")
.tasklet(new CustomTasklet())
.build();
}
}
public class CustomTasklet implements Tasklet {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("step3 has executed");
return RepeatStatus.FINISHED;
// Tasklet 인터페이스의 execute 메서드를 구현하며
// 처리 완료 이후 스프링 배치가 어떤 일을 수행해야 할지 알 수 있도록 RepeatStatus 객체를 반환하게 만든다.
}
}