diff --git a/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextConfiguration.java b/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextConfiguration.java new file mode 100644 index 00000000..7e176dd0 --- /dev/null +++ b/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextConfiguration.java @@ -0,0 +1,64 @@ +package io.springbatch.basic.executioncontext; + +import lombok.RequiredArgsConstructor; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.JobBuilderFactory; +import org.springframework.batch.core.configuration.annotation.StepBuilderFactory; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/* + JobExecution, StepExecution 객체의 상태를 저장하는 공유 객체 + DB에 직렬화 한 값으로 저장 ( {"key" : "value"} ) + 각 Step 의 StepExecution 에 저장되고 Step 간 공유 안됨 + 각 Job 의 JobExecution 에 저장되고 Job 간 공유 안됨, 해당 Job 의 Step 간 서로 공유 + */ +@Configuration +@RequiredArgsConstructor +public class ExecutionContextConfiguration { + + private final JobBuilderFactory jobBuilderFactory; + private final StepBuilderFactory stepBuilderFactory; + private final ExecutionContextTasklet1 executionContextTasklet1; + private final ExecutionContextTasklet2 executionContextTasklet2; + private final ExecutionContextTasklet3 executionContextTasklet3; + private final ExecutionContextTasklet4 executionContextTasklet4; + + @Bean + public Job job() { + return jobBuilderFactory.get("job") + .start(step1()) + .next(step2()) + .next(step3()) + .next(step4()) + .build(); + } + + @Bean + public Step step1() { + return stepBuilderFactory.get("step1") + .tasklet(executionContextTasklet1) + .build(); + } + + @Bean + public Step step2() { + return stepBuilderFactory.get("step2") + .tasklet(executionContextTasklet2) + .build(); + } + @Bean + public Step step3() { + return stepBuilderFactory.get("step3") + .tasklet(executionContextTasklet3) + .build(); + } + @Bean + public Step step4() { + return stepBuilderFactory.get("step4") + .tasklet(executionContextTasklet4) + .build(); + } +} diff --git a/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet1.java b/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet1.java new file mode 100644 index 00000000..7708690f --- /dev/null +++ b/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet1.java @@ -0,0 +1,36 @@ +package io.springbatch.basic.executioncontext; + +import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.scope.context.ChunkContext; +import org.springframework.batch.core.step.tasklet.Tasklet; +import org.springframework.batch.item.ExecutionContext; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.stereotype.Component; + +@Component +public class ExecutionContextTasklet1 implements Tasklet { + + @Override + public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { + System.out.println("step1 was executed"); + + ExecutionContext jobExecutionContext = contribution.getStepExecution().getJobExecution().getExecutionContext(); + ExecutionContext stepExecutionContext = contribution.getStepExecution().getExecutionContext(); + + String jobName = chunkContext.getStepContext().getStepExecution().getJobExecution().getJobInstance().getJobName(); + String stepName = chunkContext.getStepContext().getStepExecution().getStepName(); + + if (jobExecutionContext.get("jobName") == null) { + jobExecutionContext.put("jobName", jobName); + } + + if (stepExecutionContext.get("stepName") == null) { + stepExecutionContext.put("stepName", stepName); + } + + System.out.println("jobName = " + jobExecutionContext.get("jobName")); + System.out.println("stepName = " + stepExecutionContext.get("stepName")); + + return RepeatStatus.FINISHED; + } +} diff --git a/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet2.java b/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet2.java new file mode 100644 index 00000000..257c7dc1 --- /dev/null +++ b/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet2.java @@ -0,0 +1,31 @@ +package io.springbatch.basic.executioncontext; + +import org.springframework.batch.core.StepContribution; +import org.springframework.batch.core.scope.context.ChunkContext; +import org.springframework.batch.core.step.tasklet.Tasklet; +import org.springframework.batch.item.ExecutionContext; +import org.springframework.batch.repeat.RepeatStatus; +import org.springframework.stereotype.Component; + +@Component +public class ExecutionContextTasklet2 implements Tasklet { + + @Override + public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { + System.out.println("step2 was executed"); + + ExecutionContext jobExecutionContext = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext(); + ExecutionContext stepExecutionContext = chunkContext.getStepContext().getStepExecution().getExecutionContext(); + + System.out.println("jobName = " + jobExecutionContext.get("jobName")); + System.out.println("stepName = " + stepExecutionContext.get("stepName")); + + String stepName = chunkContext.getStepContext().getStepExecution().getStepName(); + + if (stepExecutionContext.get("stepName") == null) { + stepExecutionContext.put("stepName", stepName); + } + + return RepeatStatus.FINISHED; + } +} diff --git a/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet3.java b/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet3.java new file mode 100644 index 00000000..57da5e98 --- /dev/null +++ b/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet3.java @@ -0,0 +1,29 @@ +package io.springbatch.basic.executioncontext; + +import org.springframework.batch.core.StepContribution; +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.stereotype.Component; + +@Component +public class ExecutionContextTasklet3 implements Tasklet { + + @Override + public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { + System.out.println("step3 was executed"); + + Object name = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().get("name"); + + if (name == null) { + chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().put("name", "user1"); + + // 처음에는 name 이 null 이므로 예외 발생 + // 재실행 시에는 JobExecution 의 ExecutionContext 을 공유하므로 + // name 이 null 이 아니므로 예외 발생 하지 않고 수행 된다. + throw new RuntimeException("step3 was failed"); + } + + return RepeatStatus.FINISHED; + } +} diff --git a/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet4.java b/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet4.java new file mode 100644 index 00000000..71560889 --- /dev/null +++ b/spring-batch/basic/src/main/java/io/springbatch/basic/executioncontext/ExecutionContextTasklet4.java @@ -0,0 +1,21 @@ +package io.springbatch.basic.executioncontext; + +import org.springframework.batch.core.StepContribution; +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.stereotype.Component; + +@Component +public class ExecutionContextTasklet4 implements Tasklet { + + @Override + public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { + System.out.println("step4 was executed"); + + Object name = chunkContext.getStepContext().getStepExecution().getJobExecution().getExecutionContext().get("name"); + System.out.println("name = " + name); + + return RepeatStatus.FINISHED; + } +} diff --git a/spring-batch/basic/src/main/java/io/springbatch/basic/step/stepcontribution/StepContributionConfiguration.java b/spring-batch/basic/src/main/java/io/springbatch/basic/step/stepcontribution/StepContributionConfiguration.java index 49148055..0ffd7435 100644 --- a/spring-batch/basic/src/main/java/io/springbatch/basic/step/stepcontribution/StepContributionConfiguration.java +++ b/spring-batch/basic/src/main/java/io/springbatch/basic/step/stepcontribution/StepContributionConfiguration.java @@ -9,7 +9,7 @@ import org.springframework.batch.repeat.RepeatStatus; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -@Configuration +//@Configuration @RequiredArgsConstructor public class StepContributionConfiguration {