
Spring Batch에서 파일로 데이터를 저장할 때 사용하는 Writer가 FlatFileItemWriter이다. 이 Writer의 역할은 단순하다. 객체를 문자열로 변환한 뒤 파일에 기록하는 것이다.
배치 처리의 기본 흐름은 다음과 같다.
Reader → Processor → Writer
Reader는 데이터를 읽어 객체로 만들고, Processor는 객체를 가공하며, Writer는 가공된 결과를 저장한다. 저장 대상이 파일인 경우에는 객체를 그대로 기록할 수 없다. 파일에는 결국 문자열이 기록되기 때문이다. 따라서 FlatFileItemWriter는 Step에서 전달받은 객체를 파일에 기록 가능한 문자열로 변환한 뒤 이를 파일에 한 줄씩 기록하는 역할을 한다.
먼저 파일로 기록할 간단한 객체를 하나 가정해 보자. Step에서 다음과 같은 객체가 Writer로 전달된다고 하자.
new ErrorLog(
"ERR-001",
"2024-01-25 10:15:23",
"CRITICAL",
"Database connection failure"
)
이 객체는 파일에 다음과 같은 문자열 형태로 기록될 수 있다.
ERR-001,2024-01-25 10:15:23,CRITICAL,Database connection failure
즉 FlatFileItemWriter의 핵심 작업은 객체를 문자열 한 줄로 변환한 뒤 그 문자열을 파일에 기록하는 것이다. 이 변환 과정은 두 단계로 이루어진다. 먼저 객체에서 필요한 값을 추출하고, 그 다음 추출한 값들을 하나의 문자열로 결합한다.
객체를 문자열로 만들기 위해서는 먼저 객체에서 필요한 값을 꺼내야 한다. 이 역할을 하는 것이 FieldExtractor이다. FieldExtractor는 객체를 입력으로 받아 파일에 기록할 필드 값들을 배열 형태로 추출한다.
인터페이스는 다음과 같다.
public interface FieldExtractor<T> {
Object[] extract(T item);
}
앞에서 사용한 ErrorLog 객체를 기준으로 보면 FieldExtractor는 객체의 필드를 순서대로 꺼내어 다음과 같은 값 배열을 만든다.
["ERR-001", "2024-01-25 10:15:23", "CRITICAL", "Database connection failure"]
즉 FieldExtractor는 객체 전체를 그대로 파일에 쓰는 것이 아니라 객체에서 필요한 값을 추출하고 그 순서를 정의하는 역할을 담당한다.
LineAggregator는 추출된 필드 값을 하나의 문자열로 결합하는 역할을 한다. 즉 객체 데이터를 파일에 기록할 최종 문자열 한 줄로 변환하는 컴포넌트이다.
인터페이스는 다음과 같다.
public interface LineAggregator<T> {
String aggregate(T item);
}
예를 들어 FieldExtractor가 추출한 값이 다음과 같다고 하자.
["ERR-001", "2024-01-25 10:15:23", "CRITICAL", "Database connection failure"]
이 값을 CSV 형식으로 결합하면 다음과 같은 문자열이 된다.
ERR-001,2024-01-25 10:15:23,CRITICAL,Database connection failure
이 과정에서 LineAggregator는 내부적으로 FieldExtractor를 사용해 필드를 추출한 뒤, 그 값을 원하는 형식으로 결합하여 하나의 문자열을 생성한다.
문자열이 생성되면 FlatFileItemWriter는 이를 실제 파일에 기록한다. 내부적으로는 BufferedWriter를 사용하여 문자열을 파일에 한 줄씩 기록한다. 즉 FlatFileItemWriter의 전체 동작은 다음과 같은 흐름으로 이해할 수 있다. Step에서 전달된 객체가 LineAggregator를 통해 문자열로 변환되고, 그 결과 문자열이 파일에 기록된다.