📚FOS Study
홈카테고리
홈카테고리
📚FOS Study

개발 학습 기록을 정리하는 블로그입니다.

바로가기

  • 홈
  • 카테고리

소셜

  • GitHub
  • Source Repository

© 2025 FOS Study. Built with Next.js & Tailwind CSS

목록으로 돌아가기
☕java/ spring-framework

FlatFileItemWriter

약 3분
GitHub에서 보기

FlatFileItemWriter

  • 데이터를 플랫 파일 형식으로 쓰는 작업을 담당
  • 데이터를 파일에 쓸 때 흔히 발생하는 복잡한 저수준 작업들, 파일 포맷 맞추기, 데이터를 한 줄씩 작성, 내부적으로 버퍼링을 활용한 최적화 등의 귀찮은 일들을 직접 구현할 필요가 없음
  • 선언적인 설정만으로 대량의 파일 쓰기 작업을 효율적으로 처리할 수 있음

  • 어떻게 도메인 객체를 파일에 기록할까?
    • 먼저 도메인 객체의 각 필드 값을 추출한다.
    • 만약 CSV 형식으로 기록해야 한다면, 각 정보를 콤마(,)로 이어서 문자열을 만든다
      • 특별한 형식이 필요하다면, 원하는 대로 포맷팅 할 수 있다
    • FlatFileItemWriter 내부에서
      • 필드 추출 역할은 FieldExtractor
      • 문자열로 결합하는 역할은 LineAggregator 컴포넌트가 맡는다

필드 추출과 라인 결합

  • 1단계 : FieldExtractor(필드 추출)
    • 도메인 객체에서 필드를 추출하는 역할을 한다.
    • 인터페이스는 다음과 같다
      public interface FieldExtractor<T> {
          Object[] extract(T item);
      }
    
    • Spring Batch가 제공하는 대표적인 FieldExtractor에는 두 가지가 있다.
      • BeanWrapperFieldExtractor
        • Java Bean 객체로부터 필드를 추출하는 FieldExtractor
        • 객체의 프로퍼티 이름들을 기반으로 getter 메서드를 호출하여 필드값을 추출
      • RecordFieldExtractor
        • Java Record 객체에서 필드를 추출하는 FieldExtractor
        • 레코드 컴포넌트의 accessor 메서드를 호출하여 값을 가져옴
    • Spring Batch는 파일에 쓸 도메인 객체의 타입에 따라 두 구현체 중 하나를 자동으로 선택함
  • 2단계 : LineAggregator(문자열 결합)
    • FieldExtractor에서 추출한 데이터들을 하나의 문자열로 결합하는 역할
    • CSV 형식으로 결합할 수도 있고, 커스텀 형식으로 데이터를 포맷할 수도 있음
      • DelimtedLineAggregator : 구분자 기반 형식으로 문자열 결합
      • FormatterLineAggregator : 고정 길이 형식을 포함한 다른 형식으로 문자열 결합

동작 구조

  • FlatFileItemWriter -> LineAggregator 구조
+--------------------------------------------------+
|               FlatFileItemWriter<T>              |
|--------------------------------------------------|
|  - lineAggregator : LineAggregator<T>            |
+--------------------------------------------------+
                         |
                         v
+--------------------------------------------------+
|        <<interface>> LineAggregator<T>            |
|--------------------------------------------------|
|  + aggregate(item : T) : String                  |
+--------------------------------------------------+
                         ^
                         |
+--------------------------------------------------+
|     <<abstract>> ExtractorLineAggregator<T>       |
|--------------------------------------------------|
|  - fieldExtractor : FieldExtractor<T>            |
|--------------------------------------------------|
|  + aggregate(item : T) : String                  |
|  # doAggregate(fields : Object[]) : String       |
+--------------------------------------------------+
                ^                          ^
                |                          |
+-------------------------------+   +-------------------------------+
|  DelimitedLineAggregator<T>   |   |  FormatterLineAggregator<T>   |
|-------------------------------|   |-------------------------------|
|  - delimiter : String         |   |  - format : String            |
|-------------------------------|   |-------------------------------|
|  doAggregate(fields)          |   |  doAggregate(fields)          |
+-------------------------------+   +-------------------------------+
  • 동작 순서도
Item<T>
  |
  v
FlatFileItemWriter.write()
  |
  v
LineAggregator.aggregate(item)
  |
  v
ExtractorLineAggregator.aggregate(item)
  |
  +--> FieldExtractor.extract(item)
  |        |
  |        v
  |     Object[] fields
  |
  +--> doAggregate(fields)
           |
           +--> DelimitedLineAggregator
           |       -> "a,b,c"
           |
           +--> FormatterLineAggregator
                   -> String.format(...)

  • 지금까지는 객체 하나를 문자열로 바꾸는 법을 살펴봤다

    • 하지만 ItemWriter의 write() 메서드는 단일 객체가 아닌 Chunk를 입력받는다는 것을 기억하자
    • Chunk에는 여러 아이템이 들어있으니, FlatFileItemWriter는 각 아이템마다 이 과정을 반복한다
    // FlatFileItemWriter.doWrite() -> write()에서 호출
    public String doWrite(Chunk<? extends T> items) {
      StringBuilder lines = new StringBuilder();
      for (T item : items) {
        lines.append(this.lineAggregator.aggregate(item)).append(this.lineSeparator);
      }
      return lines.toString();
    }
    
java 카테고리의 다른 글 보기수정 제안하기
목차
  • FlatFileItemWriter
  • 필드 추출과 라인 결합
  • 동작 구조