flowJob 을 구성할 때
stop on to end를 연결하여 하나의 flow를 연결하였다.
step은 일종의 buisiness 로직을 담는 부분인데
stop on to end와 강한 결합이 생기고
on to end 이런 api가 복잡하게 구성될 수 있다.
여러 step을 구성하다보면 전체적인 step을 파악하기가 어렵다.
jobExecutionDecider는 Transition 처리를 위한 전용 클래스 이기 때문에
내부적인 로직을 통해 flow 흐름을 제어할 수 있다.
훨씬 간단하게 심플하게 구성할 수 있다.
transitional api를 사용하는 보다 더 깔끔하게 구성할 수 있다.
configuration
package io.springbatch.springbatch.jobExecutionDecider;
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.job.flow.Flow;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
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;
@RequiredArgsConstructor
@Configuration
public class JobExecutionDeciderConfiguration {
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
@Bean
public Job jobExecutionDecider() {
return jobBuilderFactory.get("jobExecutionDeciderjob")
.incrementer(new RunIdIncrementer())
.start(jobExecutionDeciderStep1())
.next(decider())
.from(decider()).on("ODD").to(jobExecutionDeciderOddStep())
.from(decider()).on("EVEN").to(jobExecutionDeciderEvenStep())
.end()
.build();
}
@Bean
public JobExecutionDecider decider() {
return new CustomDecider();
}
@Bean
public Step jobExecutionDeciderStep1() {
return stepBuilderFactory.get("deciderStep1")
.tasklet((stepContribution, chunkContext) -> {
System.out.println("decider step1 was executed");
return RepeatStatus.FINISHED;
}).build();
}
@Bean
public Step jobExecutionDeciderEvenStep() {
return stepBuilderFactory.get("evenStep1")
.tasklet((stepContribution, chunkContext) -> {
System.out.println("even step was executed");
return RepeatStatus.FINISHED;
}).build();
}
@Bean
public Step jobExecutionDeciderOddStep() {
return stepBuilderFactory.get("oddStep1")
.tasklet((stepContribution, chunkContext) -> {
System.out.println("odd step was executed");
return RepeatStatus.FINISHED;
}).build();
}
}
decider
package io.springbatch.springbatch.jobExecutionDecider;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
public class CustomDecider implements JobExecutionDecider {
private int count = 0;
@Override
public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
count ++;
if (count % 2 == 0) {
return new FlowExecutionStatus("EVEN");
} else {
return new FlowExecutionStatus("ODD");
}
}
}
SimpleFlow의 start() 메서드가 호출된다.
이후 resume 메서드가 호출된다.
status는 decider를 가지고 있따.
state.handler 하게 되면 customdecider가 호출된다.
decisionStatue는 내부에 decider를 가지고 있고
이때 customDecider가 호출된다.
'강의 > 스프링배치' 카테고리의 다른 글
스프링 배치 - SimpleFlow (0) | 2023.01.30 |
---|---|
Flowjob architecture (0) | 2023.01.30 |
스프링 배치 - 사용자 정의 ExitStatus (0) | 2023.01.29 |
스프링 배치 실행 - Transition (0) | 2023.01.27 |
SpringBatch - Transition - 배치상태 유형 (BatchStatus / ExitStatus / FlowExecutionStatus) (0) | 2023.01.25 |