티스토리 뷰
Spring Batch jobParameters 사용하는 방법 (with @JobScope, @StepScope)
호형 2020. 11. 4. 18:01Spring Batch에서 실행할때 넘겨주는 Parameter 값을 받아서 동적으로 처리를 하고 싶은 경우가 있다.
Springboot Batch에서는 이렇게 Program Arguments를 이용해 jobParameters를 전달한다. 바로 이 값을 어떻게 Batch 코드에서 받을수 있을까에 대한 이야기를 해보려 한다.
jobParameters도 기본적으로 값을 받을때 @Value("#{jobParameters[testKey]}") 이런 형식으로 값을 받아야한다. 그냥 코드에 딸랑 저것만 넣으면 안된다. 이걸 사용할 수 있게 해주는것이 바로 @StepScope, @JobScope이다. 이것의 뜻은 Step 실행시점에 bean이 생성이 되는것, 혹은 Job 실행시점에 bean이 생성이 되는것이다. 지난번 yaml 파일의 값을 가지고 오면서 삽질을 한번 한 경험이 있어서 그런지 왜 이런것들을 써야 하는지 이해를 할수 있었다.
간단하게 정리하면 배치의 구성요소중
Tasklet, Reader, Processor, Writer 를 사용할때 jobParameters를 가져오고 싶으면 각 메소드 위에 @StepScope를 붙여주고 한단계 위인 Step에서 jobParameters를 가져오고 싶으면 Step 정의 메소드 위에 @JobScope를 붙여준다.
Chunk(Reader, Processor, Writer), Tasklet - @StepScope
reader 예제
@StepScope
@Bean
public FlatFileItemReader<Employee> testReader(@Value("#{jobParameters[testKey]}") String testKey) {
log.info("############################" + testKey);
return new FlatFileItemReaderBuilder<Employee>()
.name("flatFileItemReader")
.resource(new ClassPathResource("us-500.csv"))
.delimited()
.names(new String[]{"first_name", "last_name", "company_name", "address", "city", "county", "state", "zip", "phone1", "phone2", "email", "web"})
.fieldSetMapper(new BeanWrapperFieldSetMapper<Employee>() {{
setTargetType(Employee.class);
}})
.build();
}
@Bean
public Step sampleChunkStep(SampleStepListener stepListener, JdbcBatchItemWriter<Employee> testWriter) {
return stepBuilderFactory.get("sampleChunkStep")
.listener(stepListener)
.<Employee, Employee> chunk(10)
.reader(testReader(null))
.processor(testProcessor())
.writer(testWriter)
.build();
}
@StepScope를 붙인 부분과 testReader 메소드 argument로 jobParameters 받는 부분, 그리고 step에서 reader를 호출할때 null 값을 넣어서 보내주는 부분정도 유심히 보면 될듯 싶다.
tasklet 예제
@Bean
public Step sampleTaskletStep(SampleStepListener stepListener) {
return stepBuilderFactory.get("sampleTaskletStep")
.tasklet(sampleTasklet1(null))
.build();
}
@Bean
@StepScope
public Tasklet sampleTasklet1(@Value("#{jobParameters[testKey]}") String testKey) {
return (contribution, chunkContext) -> {
log.info("############################" + testKey);
return RepeatStatus.FINISHED;
};
}
앞서 설명한 reader와 같은 레벨이니 거의 동일하게 사용한다고 보면 된다. testKey에 대한 값을 잘 가져온다.
Step - @JobScope
tasklet 예제
@Bean
public Job sampleTaskletJob() {
return jobBuilderFactory.get("sampleTaskletJob")
.incrementer(new RunIdIncrementer())
.start(sampleTaskletStep(null))
.build();
}
@Bean
@JobScope
public Step sampleTaskletStep(@Value("#{jobParameters[testKey]}") String testKey) {
log.info("############################" + testKey);
return stepBuilderFactory.get("sampleTaskletStep")
.tasklet(sampleTasklet1())
.build();
}
@StepScope와 사용법은 거의 동일하고 한 depth 위로 올라간 개념이라고 보면 된다.
단 Step을 실행시킬때 start()로 하지 않고 flow()로 하는건 이 방법이 통하지 않는다. flow를 사용하고 싶을때는 Flow 객체를 생성해서 사용하는 방법을 이용해보자.
끝!
'Framework > Batch' 카테고리의 다른 글
[Spring Batch] Chunk Example (DB to File, Springboot based) (0) | 2021.03.10 |
---|---|
Spring Batch 오류시 exitCode 설정하여 Jenkins에서 실패로 인식하도록 하는 방법 (0) | 2020.11.30 |
[Spring Batch] Skip/Retry Simple Example (Springboot based) (0) | 2020.10.27 |
[Spring Batch] Parallel(병렬처리) Example (Springboot based) (0) | 2020.10.27 |
[Spring Batch] Tasklet Example (Springboot based) (0) | 2020.10.26 |