반응형
728x90
반응형
Listner 생성 및 설정
JobRepositoryListener.java
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.batch.core.*;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.stereotype.Component;
@Component
@RequiredArgsConstructor
@Slf4j
public class JobRepositoryListener implements JobExecutionListener {
private final JobRepository jobRepository;
@Override
public void beforeJob(JobExecution jobExecution) {
}
@Override
public void afterJob(JobExecution jobExecution) {
String jobName = jobExecution.getJobInstance().getJobName();
// 실제로 저장된 데이터로 셋팅
// BATH_JOB_EXECUTION_PARAMS : JOB_EXECUTION_ID
JobParameters jobParameters = new JobParametersBuilder()
.addString("requestDate", "20220526").toJobParameters();
// jobParameters 는 DB 에 저장되어있는 데이터를 가져온다.
JobExecution lastJobExecution = jobRepository.getLastJobExecution(jobName, jobParameters);
if (lastJobExecution != null) {
for (StepExecution stepExecution : lastJobExecution.getStepExecutions()) {
BatchStatus status = stepExecution.getStatus();
ExitStatus exitStatus = stepExecution.getExitStatus();
log.info("BatchStatus : {}, ExitStatus : {}", status, exitStatus);
String stepName = stepExecution.getStepName();
log.info("stepName : {}", stepName);
}
}
}
}
1) JobParameters 객체 생성하기
// 실제로 저장된 데이터로 셋팅
// BATH_JOB_EXECUTION_PARAMS : JOB_EXECUTION_ID
JobParameters jobParameters = new JobParametersBuilder()
.addString("requestDate", "20220526").toJobParameters();
2) JobRepository 로 가장 마지막에 실행된 JobExecution 가져오기
// jobParameters 는 DB 에 저장되어있는 데이터를 가져온다.
JobExecution lastJobExecution = jobRepository.getLastJobExecution(jobName, jobParameters);
3) JobExecution 에서 StepExecution 여러개를 가져온다.
if (lastJobExecution != null) {
for (StepExecution stepExecution : lastJobExecution.getStepExecutions()) {
BatchStatus status = stepExecution.getStatus();
ExitStatus exitStatus = stepExecution.getExitStatus();
log.info("BatchStatus : {}, ExitStatus : {}", status, exitStatus);
String stepName = stepExecution.getStepName();
log.info("stepName : {}", stepName);
}
}
- JobExecution.getStepExecutions() 내부 로직
public Collection<StepExecution> getStepExecutions() {
return Collections.unmodifiableList(new ArrayList<>(stepExecutions));
}
Job 생성
JobRepositoryConfiguration.java
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecutionListener;
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.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;
/*
--job.name=jobRepositoryTestJob
*/
/**
* SimpleStepHandler.java
* AbstractStep.java
* TaskletStep.java
*/
@Configuration
@RequiredArgsConstructor
public class JobRepositoryConfiguration {
// job 생성
private final JobBuilderFactory jobBuilderFactory;
private final StepBuilderFactory stepBuilderFactory;
// listener
private final JobRepositoryListener jobRepositoryListener;
@Bean
public Job jobRepositoryTestJob() {
return this.jobBuilderFactory.get("jobRepositoryTestJob")
.start(jobRepositoryStep1())
.next(jobRepositoryStep2())
.listener(jobRepositoryListener) // 리스너 적용
.build();
}
@Bean
public Step jobRepositoryStep1() {
return stepBuilderFactory.get("jobRepositoryStep1")
.tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("jobRepositoryStep1");
return RepeatStatus.FINISHED;
}
})
.build();
}
@Bean
public Step jobRepositoryStep2() {
return stepBuilderFactory.get("jobRepositoryStep2")
.tasklet(new Tasklet() {
@Override
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
System.out.println("jobRepositoryStep2");
return RepeatStatus.FINISHED;
}
})
.build();
}
}
1) 리스너 설정
@Bean
public Job jobRepositoryTestJob() {
return this.jobBuilderFactory.get("jobRepositoryTestJob")
.start(jobRepositoryStep1())
.next(jobRepositoryStep2())
.listener(jobRepositoryListener) // 리스너 적용
.build();
}
배치 실행
program-arguments
--job.name=jobRepositoryTestJob requestDate=20220526
디버깅
if (lastJobExecution != null) {
for (StepExecution stepExecution : lastJobExecution.getStepExecutions()) {
BatchStatus status = stepExecution.getStatus();
ExitStatus exitStatus = stepExecution.getExitStatus();
log.info("BatchStatus : {}, ExitStatus : {}", status, exitStatus);
String stepName = stepExecution.getStepName();
log.info("stepName : {}", stepName);
}
}
결과
jobRepositoryStep1
jobRepositoryStep2
BatchStatus : COMPLETED, ExitStatus : exitCode=COMPLETED;exitDescription=
stepName : jobRepositoryStep1
BatchStatus : COMPLETED, ExitStatus : exitCode=COMPLETED;exitDescription=
stepName : jobRepositoryStep2
배치 재수행
이제 배치를 재수행해보자.
program-arguments
--job.name=jobRepositoryTestJob requestDate=20220527
디버깅
@Override
public void afterJob(JobExecution jobExecution) {
String jobName = jobExecution.getJobInstance().getJobName();
// 실제로 저장된 데이터로 셋팅
// BATH_JOB_EXECUTION_PARAMS : JOB_EXECUTION_ID
JobParameters jobParameters = new JobParametersBuilder()
.addString("requestDate", "20220526").toJobParameters();
// jobParameters 는 DB 에 저장되어있는 데이터를 가져온다.
JobExecution lastJobExecution = jobRepository.getLastJobExecution(jobName, jobParameters);
if (lastJobExecution != null) {
for (StepExecution stepExecution : lastJobExecution.getStepExecutions()) {
BatchStatus status = stepExecution.getStatus();
ExitStatus exitStatus = stepExecution.getExitStatus();
log.info("BatchStatus : {}, ExitStatus : {}", status, exitStatus);
String stepName = stepExecution.getStepName();
log.info("stepName : {}", stepName);
}
}
}
1) 현재 실행중인 JobExecution
2) 위 코드의 lastJobExecution
결론
20220526 파라미터에 해당하는 Job 중 가장 최신의 JobExecution을 가져온다.
반응형
'Coding > Spring Batch' 카테고리의 다른 글
[SpringBatch 실습] 10. STEP의 EXIT_CODE, STATUS 설정하기 (0) | 2022.05.28 |
---|---|
[SpringBatch 실습] 9. FlowBuilder를 사용해서 FlowJob 생성하기 (0) | 2022.05.27 |
[SpringBatch 실습] 7. BATCH 테이블 Prefix 변경해보기 (0) | 2022.05.26 |
[SpringBatch 실습] 6. ExecutionContext (StepExecution, JobExecution 관계) 예제로 흐름 파악하기 (0) | 2022.05.24 |
[SpringBatch 실습] 5. Batch Job 수행시 Step 실패하는 경우2 (Step 실패와 StepExceution 관계) (0) | 2022.05.23 |