반응형
주저리
spring boot를 사용하여
spring batch를 해보려는데 막상 spring batch를 잘모르면 제대로 못할것 같은 생각이 들었다.
springframework를 spring boot기반으로 해볼때도 마찬가지였다.
구성
- Job과 Step으로 구성.
- Job
- 여러개의 Step으로 구성.
- Step은 ItemReader, ItemProcessor, ItemWriter의 구조이거나
이런 전형적인 구조가 아닐 경우 Tasklet 구조.
분석
2018/09/12 - [OpenSource/Spring Batch] - SpringBatch 예제
에서 처럼 https://spring.io/guides/gs/batch-processing/
공식 사이트를 살펴보도록 하자.
org.springframework.boot:spring-boot-starter-batch 디펜던시는 요녀석!
Batch Job을 구성할 때
Spring Batch는 따로 작성할 필요없이 비즈니스 로직에 집중할 수 있도록 많은 유틸리티를 제공한다.
BatchConfiguration! 이부분은 옛날 Spring Batch에서 xml로 구성되던 녀석이다.
@Configuration
@EnableBatchProcessing
public class BatchConfiguration {
하나하나씩 보도록 하자. 우선 Factory를 DI 하는 것을 볼수 있다.
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
Factory는 Job과 Step에서 사용!
// tag::jobstep[]
@Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1)
.end()
.build();
}
@Bean
public Step step1(JdbcBatchItemWriter<Person> writer) {
return stepBuilderFactory.get("step1")
.<Person, Person> chunk(10)
.reader(reader())
.processor(processor())
.writer(writer)
.build();
}
// end::jobstep[]
그리고 Step에서 사용되어지는 reader, processor, writer도 함께 구성.
// tag::readerwriterprocessor[]
@Bean
public FlatFileItemReader<Person> reader() {
return new FlatFileItemReaderBuilder<Person>()
.name("personItemReader")
.resource(new ClassPathResource("sample-data.csv"))
.delimited()
.names(new String[]{"firstName", "lastName"})
.fieldSetMapper(new BeanWrapperFieldSetMapper<Person>() {{
setTargetType(Person.class);
}})
.build();
}
@Bean
public PersonItemProcessor processor() {
return new PersonItemProcessor();
}
@Bean
public JdbcBatchItemWriter<Person> writer(DataSource dataSource) {
return new JdbcBatchItemWriterBuilder<Person>()
.itemSqlParameterSourceProvider(new BeanPropertyItemSqlParameterSourceProvider<>())
.sql("INSERT INTO people (first_name, last_name) VALUES (:firstName, :lastName)")
.dataSource(dataSource)
.build();
}
// end::readerwriterprocessor[]
구조는 이러하고..이제 조금 더 자세하게 보도록 하자.
More and More
BatchConfiguration.java
- @Configuration : 설정 파일임을 알려준다. @MVC에서 @service @controller와 같다고 보면 된다.
- @EnableBatchProcessing : Batch 관련 유용한 유틸을 제공가능케 한다. 영어 고대로 Enable하겠다는 뜻.
- 위에서 언급한 내용처럼 Factory를 DI 하여 Job과 Step을 구성한다.
- Job은 Step으로 구성하여 만들어지고 Step은 reader, processor, writer를 구성할 수 있다.
- 어노테이션 @Autowired로 DI 해주는 부분.
@Autowired
public JobBuilderFactory jobBuilderFactory;
@Autowired
public StepBuilderFactory stepBuilderFactory;
- Job과 Step을 설정 해주는 부분.
@Bean
public Job importUserJob(JobCompletionNotificationListener listener, Step step1) {
return jobBuilderFactory.get("importUserJob")
.incrementer(new RunIdIncrementer())
.listener(listener)
.flow(step1)
.end()
.build();
}
@Bean
public Step step1(JdbcBatchItemWriter<Person> writer) {
return stepBuilderFactory.get("step1")
.<Person, Person> chunk(10)
.reader(reader())
.processor(processor())
.writer(writer)
.build();
}
- Job은 아래와 같이 importUserJob이라는 함수명을 가지며, 파라미터로는 listener, step을
- return으로는 JobBuilderFactory를 이용하여 Job을 리턴하는 구조이다.
- jobBuilderFactory.get은 job builder를 생성하고 JobRepository를 초기화 시킨다.
[ Spring Batch 흐름도]
|
- 아래를 좀 더 심화있게 이해하려면 builder pattern을 이해해야한다.
- 하지만 우선적으로 Spring Batch에 대해서 파악하는게 우선이다.
- 이제 돌아와서 incremeter를 보자.
- JobBuilderHelper Class에 속해있는 method이다.
- JobBuilderHelper는 JobBuilder의 부모 클래스이다.
- 포맷은 아래와 같다.
- public B incrementer(JobParametersIncrementer jobParametersIncrementer)
- 파라미터로 JobPrametersIncrementer를 가지는데 이것은 Interface 형태이다.
- 이 Interface를 구현한 녀석이 위에 사용되어진 RunIdIncrementer Class 이다.
- 그리고 incrementer 이녀석이 하는 역할은 JobParametersIncrementer 인터페이스의
역할을 보면 알수 있다. JobParameters를 취득하기 위한 인터페이스이기 때문이다. - JobParameters..! 이녀석을 이해하려면 아래의 그림을 이해해야한다.
- 동시 다발적으로 돌아가는 Job들의 차이는 어떻게 알수가 있나? Job들 간의 구별? 그 해답은 JobParameters에 있다. 그래서 batch job을 시작할 때 이처럼 JobParameters를 취득한다.
더욱 더 자세한 내용은 해당 링크를 참조.
- 그 다음으로 listener.
- JobBuilderHelper Class에 속해 있는 Method이며, format은 아래와 같다.
public B listener(JobExecutionListener listener) - JobExecutionListener도 Interface이며 지금 설명하는 소스에서는
JobCompletionNotificationListener Class에서 extends하고 있다. - JobCompletionNotificationListener.java
package hello; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.JobExecution; import org.springframework.batch.core.listener.JobExecutionListenerSupport; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; @Component public class JobCompletionNotificationListener extends JobExecutionListenerSupport { private static final Logger log = LoggerFactory.getLogger(JobCompletionNotificationListener.class); private final JdbcTemplate jdbcTemplate; @Autowired public JobCompletionNotificationListener(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } @Override public void afterJob(JobExecution jobExecution) { if(jobExecution.getStatus() == BatchStatus.COMPLETED) { log.info("!!! JOB FINISHED! Time to verify the results"); jdbcTemplate.query("SELECT first_name, last_name FROM people", (rs, row) -> new Person( rs.getString(1), rs.getString(2)) ).forEach(person -> log.info("Found <" + person + "> in the database.")); } } }
- 위의 소스는 job이 BatchStatus.COMPLETED인가에 대해서 listen하고 있다. 그리고나서 JdbcTemplate를 사용한다.
- 다음으로 flow.
- JobBuilder Class에 속해 있는 Method이며, format은 아래와 같다.
public JobFlowBuilder flow(Step step)
딱 봐도 job과 step의 연결 & 수행. return으로는 a SimpleJobBuilder. - 다음으로 end. 즉, builder를 종료.
- 다음으로 build() : 호출하여 최종적으로 a job builder를 리턴.
- 이것은 bulider pattern을 참고.(잘 정리 해놓은 블로그! thx.)
지금까지 Job 관련 내용들을 살펴 보았습니다.
다음 포스팅에서는 비즈니스 로직을 당담하고 있는 Step에 대해서 알아보도록 하겠습니다.
2018/10/23 - [OpenSource/Spring Batch] - Spring Boot + Spring Batch 분석_02
반응형
'OpenSource > Spring Batch' 카테고리의 다른 글
springbatch setting시 오류: Spring Boot plugin requires Gradle 5 (5.6.x only) or Gradle 6 (6.3 or later). The current version is Gradle 4.10.3 (0) | 2020.08.06 |
---|---|
Spring Boot + Spring Batch 분석_02 (0) | 2018.10.23 |
SpringBatch 예제 (0) | 2018.09.12 |
MyBatisPagingItemReader를 사용할 때 유의점 (0) | 2015.10.02 |
Spring Batch 환경 셋팅 (0) | 2012.09.03 |