1. ItemProcessor 소개
- Spring Batch에서 ItemProcessor는 ItemReader와 ItemWriter 사이에서 비즈니스 로직을 처리하는 핵심 컴포넌트입니다.
- ItemReader로 읽어온 데이터를 ItemWriter로 쓰기 전에 변환, 검증, 필터링 등의 작업을 수행합니다.
- ItemProcessor는 Step에서 선택적으로 사용할 수 있으며, 복잡한 비즈니스 로직을 깔끔하게 분리할 수 있습니다.
1.1 ItemProcessor의 필요성
- ItemReader와 ItemWriter만으로는 단순한 읽기/쓰기만 가능합니다.
- 실제 배치 처리에서는 데이터 변환, 검증, 필터링 등의 비즈니스 로직이 필요합니다.
- Composite 패턴을 사용하여 ItemWriter나 ItemReader를 감싸는 방법도 있지만, ItemProcessor가 더 명확하고 효율적입니다.
Composite 패턴 예시
ItemWriter를 감싸서 비즈니스 로직을 추가하는 방법도 있지만, 단순한 변환의 경우 ItemProcessor가 더 적합합니다.
2. ItemProcessor 기본 인터페이스
2.1 인터페이스 구조
public interface ItemProcessor<I, O> {
O process(I item) throws Exception;
}
- 입력 타입 I와 출력 타입 O를 제네릭으로 지정합니다.
- process 메서드에서 하나의 객체를 받아 변환된 객체를 반환합니다.
- 입력과 출력 타입이 다를 수 있어 유연한 데이터 변환이 가능합니다.
2.2 기본 구현 예시
Foo를 Bar로 변환하는 예시
public class Foo {}
public class Bar {
public Bar(Foo foo) {}
}
public class FooProcessor implements ItemProcessor<Foo, Bar> {
public Bar process(Foo foo) throws Exception {
// 간단한 변환 로직: Foo를 Bar로 변환
return new Bar(foo);
}
}
public class BarWriter implements ItemWriter<Bar> {
public void write(Chunk<? extends Bar> bars) throws Exception {
// Bar 객체들을 처리
}
}
이 예시에서 FooProcessor는 Foo 타입의 객체를 받아 Bar 타입으로 변환합니다.
Step 설정에서 ItemProcessor 사용
@Bean
public Job ioSampleJob(JobRepository jobRepository, Step step1) {
return new JobBuilder("ioSampleJob", jobRepository)
.start(step1)
.build();
}
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("step1", jobRepository)
.<Foo, Bar>chunk(2, transactionManager)
.reader(fooReader())
.processor(fooProcessor())
.writer(barWriter())
.build();
}
- chunk 처리에서 입력 타입 Foo와 출력 타입 Bar를 명시합니다.
- processor() 메서드로 ItemProcessor를 설정합니다.
ItemProcessor는 선택사항
ItemReader와 ItemWriter와 달리 ItemProcessor는 Step에서 선택적으로 사용할 수 있습니다. 단순한 읽기/쓰기만 필요한 경우 생략 가능합니다.
3. ItemProcessor 체이닝
3.1 체이닝의 필요성
- 하나의 변환만으로는 복잡한 비즈니스 로직을 처리하기 어려운 경우가 있습니다.
- 여러 개의 ItemProcessor를 연결하여 단계적으로 데이터를 변환할 수 있습니다.
- CompositeItemProcessor를 사용하여 여러 프로세서를 체인처럼 연결합니다.
3.2 체이닝 구현 예시
다단계 변환 클래스 정의
public class Foo {}
public class Bar {
public Bar(Foo foo) {}
}
public class Foobar {
public Foobar(Bar bar) {}
}
public class FooProcessor implements ItemProcessor<Foo, Bar> {
public Bar process(Foo foo) throws Exception {
// Foo를 Bar로 변환
return new Bar(foo);
}
}
public class BarProcessor implements ItemProcessor<Bar, Foobar> {
public Foobar process(Bar bar) throws Exception {
// Bar를 Foobar로 변환
return new Foobar(bar);
}
}
public class FoobarWriter implements ItemWriter<Foobar>{
public void write(Chunk<? extends Foobar> items) throws Exception {
// 최종 결과 처리
}
}
이 예시에서는 Foo → Bar → Foobar로 2단계 변환을 수행합니다.