냅다 실전이다.
우리는 Job을 알고, Job안에 Step이있다는걸 알고
Step안에 ItemReader,ItemProcessor,ItemWriter가 있단 사실을 알았다.
그럼 만들어보자
//reader,processor,writer는 아직 구현되어있지 않습니다. @Slf4j @Configuration @RequiredArgsConstructor public class SyncJob { private final JobBuilderFactory jobBuilderFactory; private final StepBuilderFactory stepBuilderFactory; @Bean(name = "syncKwJob") public Job syncJob(Step syncStep) { log.info(">>>syncJob"); return jobBuilderFactory.get("syncKwJob") .start(syncStep) .build(); } @JobScope @Bean("syncStep") public Step syncStep(ItemReader<ReplaceKw> trReplaceKwReader, ItemProcessor<ReplaceKw, ReplaceKw> trReplaceKwProcessor, ItemWriter<ReplaceKw> trReplaceKwWriter) { log.info(">>syncStep"); return stepBuilderFactory.get("syncStep") .<ReplaceKw, ReplaceKw>chunk(5) // 제네릭 타입을 명확하게 명시 .reader(itemReader) .processor(itemProcessor) .writer(itemWriter) .build(); } }
별거 없다. JobBuilderFactory라는 것에 Job을 넣고, step도 명시해준다.
JobBuilderFactory?
앞서 말한 Job을 실행시켜주는 JobBuilder를 생성한다.
get()메서드를 통해 인자로 받은 name으로 Jobbuilder를 생성한다.
StepBuilderFactory도 보이는데 reader, processor, writer과 같은 메서드도 확인할 수 있다.
StepBuilderFactory
StepBuilder를 생성하는 팩토리 클래스로 get()메서드를 통해 인자로 받은 name으로 StepBuilder를 생성한다.
이 코드는 JobBuilderFactory와 동일하여 코드를 생략했다.
StepBuilder
Step을 구성하는 설정 조건에 따라 다섯개의 하위빌더 클래스를 생성하고 실제 Step생성을 위임한다.
Step을 구성하는 설정조건이란, Tasklet방식, ChunkOrientedTasklet방식, 멀티쓰레드 방식 등등 Step은 여러 방식으로 실행되기 때문에 이런 방식에 따라 빌더가 결정된다.
SprinbBuilder에 있는 <T,T>Chunk(크기)는 <reader에서 읽을 데이터타입, writer에서 받을 데이터 타입>으로 몇개씩 덩어리로 만들지 결정한다.
Step은 여러 여러방식으로 실행된다고 앞서 말하였다.
그 중 Tasklet은 복잡한 로직을 반복수행하고, Chunk는 reader,processor,writer에 따라 데이터를 가공할 수 있는데 이 Chunk지향 프로세싱에 대해 설명하겠다.
[개념]
1. ItemReader,ItemProcessor, ItemWriter 로 데이터 입력,가공, 출력을 담당
2. TaskletStep에 의해 반복 실행되며 ChunkOrientedTasklet이 실행될 때마다 새로운 트랜잭션이 생성되어 처리가 이루어짐.
3. 구현체
- ChunkProvider : ItemReader핸들링
- ChunkProcessor: ItemProcessor, ItemWriter핸들링
private ItemReader<String> itemReader() { return new ListItemReader<>(getItems()); } ⠀ private ItemProcessor<String, String> itemProcessor() { return item -> item + " now processor!!"; } ⠀ private ItemWriter<String> itemWriter() { return items -> log.info("### writer : " + items.toString()); }
ItemReader : getItems()에서 가지고온 List를 반환
다양한 입력으로 부터 데이터를 읽어서 제공하는 인터페이스 이다. 파일 스트림을 열거나종료, db커넥션을 열거나 종료, 입력장치 초기화등의 작업을 해준다.
ExecutionContext는 read와 관련된 여러가지 상태정보를 저장해서 재시작시 참조하도록 지원해준다.
ItemProcessor : 가지고온 Item에 문자열 더해서 처리
데이터를 가공, 변형, 필터링 해준다. null반환시에는 Chunk에 저장이 안되어 ItemWriter로 전달되지않는다.
ItemWriter :Chunksize 대로 읽은 String이 list로 출력
ItemReader와 1대 1 매칭이 되는 data종류들을 전달하게된다.
아이템 하나가 아닌 아이템 리스트를 전달받는다.
ItemStream
- ItemReader와 ItemWriter처리 과정 중 상태를 저장하고 오류 발생시 실패한곳에서 재실행하도록 지원한다.
- 리소스를 열고 닫거나 초기화하는 경우 사용하고 ExecutionContext를 매개변수로 받아 상태정보를 업데이트한다.
- ItemReader와 ItemWriter는 이 ItemStream을 구현하고있다.