15.3 ItemReader, ItemProcessor, ItemWriter 심화
1. FlatFileItemReader — CSV 파일 처리
@Bean
public FlatFileItemReader<MemberCsvDto> csvMemberReader() {
return new FlatFileItemReaderBuilder<MemberCsvDto>()
.name("csvMemberReader")
.resource(new ClassPathResource("data/members.csv"))
.delimited()
.names("name", "email", "age") // CSV 컬럼 순서와 필드명 매핑
.targetType(MemberCsvDto.class)
.linesToSkip(1) // 헤더 행 건너뜀
.build();
}
2. ItemProcessor — 변환 및 필터링
ItemProcessor는 각 아이템을 입력 타입에서 출력 타입으로 변환합니다. null을 반환하면 해당 아이템은 Writer로 넘어가지 않고 필터링됩니다.
@Bean
public ItemProcessor<MemberCsvDto, Member> memberCsvToEntityProcessor() {
return csvDto -> {
// 미성년자 필터링
if (csvDto.getAge() < 18) {
return null; // null 반환 = Writer에 전달 안 됨
}
// DTO를 엔티티로 변환
return Member.builder()
.name(csvDto.getName())
.email(csvDto.getEmail())
.age(csvDto.getAge())
.build();
};
}
3. CompositeItemProcessor — 프로세서 체이닝
여러 변환/검증 로직을 순서대로 연결하고 싶을 때 사용합니다.
@Bean
public CompositeItemProcessor<MemberCsvDto, Member> compositeProcessor() {
CompositeItemProcessor<MemberCsvDto, Member> processor = new CompositeItemProcessor<>();
processor.setDelegates(List.of(
new AgeFilterProcessor(), // 1단계: 나이 필터
new EmailValidateProcessor(), // 2단계: 이메일 형식 검증
new CsvToEntityProcessor() // 3단계: 최종 엔티티 변환
));
return processor;
}
4. ItemWriteListener — 쓰기 성공/실패 후처리
@Component
public class BatchWriteListener implements ItemWriteListener<Member> {
@Override
public void afterWrite(Chunk<? extends Member> items) {
log.info("{}건 성공적으로 저장", items.size());
}
@Override
public void onWriteError(Exception exception, Chunk<? extends Member> items) {
log.error("쓰기 실패! 실패한 아이템: {}", items);
// 슬랙 알림 or DLQ에 실패 항목 적재
}
}