Spring Batch ItemReader, Item Writer

Spring Batch Docs 공부 - ItemReader, ItemWriter
정찬's avatar
Jun 04, 2025
Spring Batch ItemReader, Item Writer
 

개요

 
이번 포스팅에서는 SpringBatch 공식문서의 ItemReaders, ItemWriters을 공부해보겠습니다.
 
 

Delegate Pattern Registering

 
일반적으로 ItemReaderItemWriter는 위임 패턴(delegate pattern)을 통해 래핑(wrapping)됩니다. 이 패턴은 여러 목적(예: 로깅, 트랜잭션 동기화, 상태 관리, 스레드 안전성 등)을 위해 사용됩니다. 예를 들어, SynchronizedItemStreamReader는 다른 ItemReader를 감싸고, 동기화된 방식으로 read()를 호출합니다.
Spring에서는 이처럼 래핑된 컴포넌트를 등록할 때 두 가지 방법을 제공합니다:
 

1. 직접 래핑해서 등록하기

 
@Bean public SynchronizedItemStreamReader<Foo> reader() { SynchronizedItemStreamReader<Foo> reader = new SynchronizedItemStreamReader<>(); reader.setDelegate(new FooReader()); return reader; }
 
이 방식에서는 위임 대상을 직접 설정합니다.
 

2. 빈으로 등록된 delegate를 주입받아 등록하기

 
@Bean public FooReader fooReader() { return new FooReader(); } @Bean public SynchronizedItemStreamReader<Foo> reader(FooReader delegate) { SynchronizedItemStreamReader<Foo> reader = new SynchronizedItemStreamReader<>(); reader.setDelegate(delegate); return reader; }
 
이 방법은 구성 요소 간 의존성을 더욱 명확하게 관리할 수 있어, 더 유연하고 테스트하기 쉬운 구조를 제공합니다.
 

Flat Files

 
bulk data를 교환하는 가장 일반적임 메커니즘 중 하나는 flat file입니다.
 
이 섹션에서는 Flat File들을 접근하여 읽고 쓰는 방법을 알아보겠습니다.
 

FieldSet

 
Spring Batch에서 플랫 파일을 사용할 때 가장 중요한 클래스 중 하나는 FieldSet입니다. FieldSet은 Spring Batch에서 파일으로부터 필드를 읽게해주는 추상화입니다. 대부분 파일을 읽고 String 배열을 리턴합니다.
 
아래는 FieldSet을 사용하는 예시입니다.
 
String[] tokens = new String[]{"foo", "1", "true"}; FieldSet fs = new DefaultFieldSet(tokens); String name = fs.readString(0); int value = fs.readInt(1); boolean booleanValue = fs.readBoolean(2);
JDBC를 사용했던 개발자들은 FieldSet의 사용 코드가 익숙하실겁니다. 실제로 FieldSet은 JDBC의 ResultSet과 유사합니다.
FieldSet 인터페이스는 Date, Long, BigDecimal 등과 같이 많은 옵션이 존재합니다.
 

FlatFileItemReader

 
FlatFileItemReader는 텍스트파일로부터 데이터를 읽기 위해 제공되는 Spring Batch의 구현체입니다. 이 Reader는 입력 파일로부터 줄을 읽고, 각 줄을 객체로 변환하기 위한 LineMapper를 사용합니다.
 
FlatFileItemReader는 다음과 같이 구성할 수 있습니다.
 
@Bean public FlatFileItemReader<Customer> reader() { FlatFileItemReader<Customer> reader = new FlatFileItemReader<>(); reader.setResource(new ClassPathResource("customer.csv")); reader.setLineMapper(new DefaultLineMapper<>() {{ setLineTokenizer(new DelimitedLineTokenizer() {{ setNames("firstName", "lastName", "birthDate"); }}); setFieldSetMapper(new BeanWrapperFieldSetMapper<>() {{ setTargetType(Customer.class); }}); }}); return reader; }
 
이 예시는 CSV의 파일을 읽어 각 줄을 Customer 객체로 매핑합니다.
 

FlatFileItemReader의 주요 구성 요소

 
  1. Resource
 
읽을 파일의 경로를 나타냅니다.
예: ClassPathResource, FileSystemResource
reader.setResource(new FileSystemResource("input/customers.csv"));
 
  1. LineMapper<T>
 
한 줄의 문자열을 도메인 객체로 변환하는 인터페이스입니다. 일반적으로 DefaultLineMapper를 사용합니다.
DefaultLineMapper<Customer> lineMapper = new DefaultLineMapper<>();
 
  1. LineTokenizer
 
텍스트 라인을 토큰으로 분할합니다. CSV의 경우 DelimitedLineTokenizer , 고정 길이 파일의 경우 FixedLengthTokenizer 를 사용합니다.
DelimitedLineTokenizer tokenizer = new DelimitedLineTokenizer(); tokenizer.setNames("id", "name", "email");
 
  1. FieldSetMapper<T>
 
토큰화된 데이터를 도메인 객체에 매핑합니다. 보통 BeanWrapperFieldSetMapper 를 사용하여 자동으로 필드 값을 객체에 주입합니다.
 

Simple Delimited File Reading Example

 
ID,lastName,firstName,position,birthYear,debutYear "AbduKa00,Abdul-Jabbar,Karim,rb,1974,1996", "AbduRa00,Abdullah,Rabih,rb,1975,1999", "AberWa00,Abercrombie,Walter,rb,1959,1982", "AbraDa00,Abramowicz,Danny,wr,1945,1967", "AdamBo00,Adams,Bob,te,1946,1969", "AdamCh00,Adams,Charlie,wr,1979,2003"
 
위의 파일을 읽어 Player 도메인에 매핑하는 예제를 보면서 사용법을 익혀봅시다.
 
  1. 먼저 Player 도메인을 정의합니다.
 
public class Player implements Serializable { private String ID; private String lastName; private String firstName; private String position; private int birthYear; private int debutYear; public String toString() { return "PLAYER:ID=" + ID + ",Last Name=" + lastName + ",First Name=" + firstName + ",Position=" + position + ",Birth Year=" + birthYear + ",DebutYear=" + debutYear; } // setters and getters... }
  1. LineMapper의 LineTokenizer를 정의하여 File의 각 줄을 자릅니다.
    1. 앞서 설명한것처럼 LineTokenizer는 크게 두가지 성격으로 나눌 수 있습니다.
    2. CSV와 같은 파일의 경우 DelimitedLineTokenizer
    3. 고정 길이 파일의 경우 FixedLengthTokenizer
💡 만약 한가지 파일에 복합적인 타입의 Record가 존재하는 경우
 
USER;Smith;Peter;;T;20014539;F LINEA;1044391041ABC037.49G201XX1383.12H LINEB;2134776319DEF422.99M005LI
위 파일은 3가지 타입의 Record가 존재합니다.
  1. USER로 시작하는 라인
  1. LINEA로 시작하는 라인
  1. LINEB로 시작하는 라인
 
한 파일에 많은 패턴 타입의 Record가 존재한다면, PatternMatchingCompositeLineMapper 를 사용할 수 있습니다.
 
@Bean public PatternMatchingCompositeLineMapper orderFileLineMapper() { PatternMatchingCompositeLineMapper lineMapper = new PatternMatchingCompositeLineMapper(); Map<String, LineTokenizer> tokenizers = new HashMap<>(3); tokenizers.put("USER*", userTokenizer()); tokenizers.put("LINEA*", lineATokenizer()); tokenizers.put("LINEB*", lineBTokenizer()); lineMapper.setTokenizers(tokenizers); Map<String, FieldSetMapper> mappers = new HashMap<>(2); mappers.put("USER*", userFieldSetMapper()); mappers.put("LINE*", lineFieldSetMapper()); lineMapper.setFieldSetMappers(mappers); return lineMapper; }
위 코드는 tokenizers map에 특정 패턴에 사용되는 LineTokenizer를 등록하는 방식입니다.
이처럼 특정 패턴에 맞춰 구성요소들 (Tokenizer, FieldSetMapper)를 등록할 수 있습니다.
 
  1. FieldSetMapper를 사용하여 Player 도메인에 바인딩합니다.
FieldSetMapper를 구성하는 방법은 두가지가 있습니다.
2-1. FieldSetMapper 구현체 등록
 
protected static class PlayerFieldSetMapper implements FieldSetMapper<Player> { public Player mapFieldSet(FieldSet fieldSet) { Player player = new Player(); player.setID(fieldSet.readString(0)); player.setLastName(fieldSet.readString(1)); player.setFirstName(fieldSet.readString(2)); player.setPosition(fieldSet.readString(3)); player.setBirthYear(fieldSet.readInt(4)); player.setDebutYear(fieldSet.readInt(5)); return player; } }
 
FlatFileItemReader<Player> itemReader = new FlatFileItemReader<>(); itemReader.setResource(new FileSystemResource("resources/players.csv")); DefaultLineMapper<Player> lineMapper = new DefaultLineMapper<>(); //DelimitedLineTokenizer defaults to comma as its delimiter lineMapper.setLineTokenizer(new DelimitedLineTokenizer()); lineMapper.setFieldSetMapper(new PlayerFieldSetMapper()); itemReader.setLineMapper(lineMapper); itemReader.open(new ExecutionContext()); Player player = itemReader.read();
 
ItemReader의 lineMapper에 PlayerFieldSetMapper 등록
 
2-2. BeanWrapperFieldSetMapper 를 사용하여 자동 바인딩
 
BeanWrapperFieldSetMapper를 사용하여 바인딩 로직을 자동화할 수 있습니다.
이 때 속성과 필드의 이름을 비교하여 일치하는 setter를 찾아 바인딩합니다.
 
@Bean public FieldSetMapper fieldSetMapper() { BeanWrapperFieldSetMapper fieldSetMapper = new BeanWrapperFieldSetMapper(); fieldSetMapper.setPrototypeBeanName("player"); return fieldSetMapper; } @Bean @Scope("prototype") public Player player() { return new Player(); }
 
💡 이 때 중요한점이 Player를 프로토타입 빈으로 등록해줘야 합니다.
그 이유는 각 줄에서 새로운 Player가 필요합니다. 만약 싱글톤 scope를 사용하면 같은 Player 인스턴스가 계속 재사용되어 마지막 라인의 데이터로 모두 덮어쓰이게 됩니다.

Exception Handling in Flat Files

 
플랫 파일들을 처리할 때 발생하는 예외들을 알아봅시다.
  1. IncorrectTokenCountException
    1.  
      예상 토큰 개수와 실제 개수가 다르면 발생하는 예외입니다.
      tokenizer.setNames(new String[] {"A", "B", "C", "D"}); try { tokenizer.tokenize("a,b,c"); } catch (IncorrectTokenCountException e) { assertEquals(4, e.getExpectedCount()); assertEquals(3, e.getActualCount()); }
       
      4개의 열을 예상했지만, 실제 파일에는 3개의 토큰만 발견되었기에, IncorrectTokenCountException이 발생하는 예시입니다.
       
  1. IncorrectLineLengthException
줄의 패턴이 고정 길이인 패턴에서 길이가 달라 발생하는 예외입니다.
 
tokenizer.setColumns(new Range[] { new Range(1, 5), new Range(6, 10), new Range(11, 15) }); try { tokenizer.tokenize("12345"); fail("Expected IncorrectLineLengthException"); } catch (IncorrectLineLengthException ex) { assertEquals(15, ex.getExpectedLength()); assertEquals(5, ex.getActualLength()); }
 
위 예시는 길이 15인 줄을 예상했지만, 실제로 길이가 5인 줄을 토큰화할 때 IncorrectLineLengthException이 발생하는 예시입니다.
 

FlatFileItemWriter

 
FlatFileItemWriter는 Spring Batch에서 제공하는 ItemWriter 구현체로, 데이터를 텍스트 기반의 플랫 파일(예: CSV, 고정 길이 파일 등)로 출력하는 데 사용됩니다. 이 클래스는 대용량 데이터를 효율적으로 파일에 기록할 수 있도록 설계되어 있으며, 다양한 포맷과 설정을 지원합니다.
 

FlatFileItemWriter의 주요 구성 요소

 
  1. LineAggregator<T>
    1. LineAggregator는 객체를 문자열로 변환하는 역할을 합니다. 즉, 각 아이템을 파일에 기록하기 전에 문자열 형태로 변환하는 로직을 정의합니다.
      • aggregate(T item): 주어진 아이템을 문자열로 변환합니다.
      예를 들어, CSV 파일에 데이터를 기록하려면 각 필드를 쉼표로 구분하여 하나의 문자열로 만들어야 합니다. 이러한 작업을 LineAggregator에서 수행합니다.
  1. FieldExtractor<T>
    1. FieldExtractor는 객체의 필드 값을 추출하는 역할을 합니다. LineAggregator와 함께 사용되어 객체를 문자열로 변환하는 데 필요한 필드 값을 제공합니다.
      • extract(T item): 주어진 아이템에서 필드 값을 추출하여 배열로 반환합니다.
      예를 들어, BeanWrapperFieldExtractor는 Java Bean의 프로퍼티 값을 추출하는 데 사용됩니다.
  1. Resource
    1. 출력 대상 파일을 지정합니다. 예를 들어, FileSystemResource를 사용하여 로컬 파일 시스템의 경로를 지정할 수 있습니다.
 

Simplified File Writing Example

 
단순화한 예제를 보면서 사용법을 익혀봅시다.
 
@Bean public FlatFileItemWriter itemWriter() { return new FlatFileItemWriterBuilder<Foo>() .name("itemWriter") .resource(new FileSystemResource("target/test-outputs/output.txt")) .lineAggregator(new PassThroughLineAggregator<>()) .build(); }
 
위처럼 Writer를 빈 등록하고, Job을 정의할 때 Writer를 지정해주면 됩니다.
LineAggregator는 아래와같은 방식으로 생성할 수 있습니다.
 
public class PassThroughLineAggregator<T> implements LineAggregator<T> { public String aggregate(T item) { return item.toString(); } }
 
 

FieldExtractor

 
위의 간단한 예제는 파일 쓰기 작업을 하는 가장 기본적인 용도입니다.
하지만 대부분의 상황에서는 FlatFileItemWriter 도메인 객체를 작성해야 합니다.
Write 과정(Domain to File)에서는 다음과 같은 과정이 필요합니다.
  1. Item을 Writer에게 제공
  1. Item의 Fields를 배열로 변환
  1. 결과 배열을 한 줄로 집계
 
프레임워크에서는 객체의 어떤 필드를 작성해야 하는지 알 수 있는 방법이 없으므로 FieldExtractor 를 반드시 작성해야 합니다.
 
FieldExtractor는 Spring Batch의 FlatFileItemWriter에서 객체의 필드 값을 추출하여 파일에 기록할 수 있도록 도와주는 컴포넌트입니다.
즉, 객체 → 문자열로 변환되는 과정에서 어떤 필드를 어떤 순서로 출력할지 정의하는 역할을 합니다.
FieldExtractor 구성 방식은 Reader의 FieldSetMapper와 유사하나, 반대로 Getter를 기준으로 매핑된다는 차이점이 있습니다.
 
구성 방식은 2가지가 있습니다.
 
1. 간단한 직접 정의 방식 (Builder의 .names() 사용)
 
FlatFileItemWriterBuilder를 사용하여 간단하게 필드 이름을 지정하는 방식입니다.
@Bean public FlatFileItemWriter<CustomerCredit> itemWriter(Resource outputResource) { return new FlatFileItemWriterBuilder<CustomerCredit>() .name("customerCreditWriter") .resource(outputResource) .delimited() .delimiter("|") .names("name", "credit") // Getter 기준 .build(); }
  • name, creditCustomerCredit 클래스의 getter 메서드(getName(), getCredit()) 기준으로 매핑됩니다.
  • 내부적으로 BeanWrapperFieldExtractor가 자동으로 사용됩니다.
 
2. 직접 구성 방식 (BeanWrapperFieldExtractor 명시)
좀 더 커스터마이징이 필요할 때는 FieldExtractorLineAggregator를 직접 설정해줄 수 있습니다.
@Bean public FlatFileItemWriter<CustomerCredit> itemWriter(Resource outputResource) { BeanWrapperFieldExtractor<CustomerCredit> fieldExtractor = new BeanWrapperFieldExtractor<>(); fieldExtractor.setNames(new String[] {"name", "credit"}); fieldExtractor.afterPropertiesSet(); DelimitedLineAggregator<CustomerCredit> lineAggregator = new DelimitedLineAggregator<>(); lineAggregator.setDelimiter(","); lineAggregator.setFieldExtractor(fieldExtractor); return new FlatFileItemWriterBuilder<CustomerCredit>() .name("customerCreditWriter") .resource(outputResource) .lineAggregator(lineAggregator) .build(); }
  • 필드 추출 방식과 구분자 로직을 명시적으로 설정할 수 있습니다.
  • 추후 FieldExtractorLineAggregator를 교체하거나 커스터마이징할 때 유연합니다.
 
또한 line의 패턴에 따라 Aggregator을 나눌 수 있습니다.
고정 너비 파일의 경우 DelimitedLineAggregator 대신 FormatterLineAggregator 등을 사용할 수 있습니다.
 
고정 너비 파일의 경우 다음과 같이 구성할 수 있습니다.
1. 간단한 직접 정의 방식 (Builder의 .names() 사용)
 
@Bean public FlatFileItemWriter<CustomerCredit> itemWriter(Resource outputResource) throws Exception { return new FlatFileItemWriterBuilder<CustomerCredit>() .name("customerCreditWriter") .resource(outputResource) .formatted() .format("%-9s%-2.0f") .names(new String[] {"name", "credit"}) .build(); }
 
  1. 직접 구성 방식 (BeanWrapperFieldExtractor 명시)
@Bean public FlatFileItemWriter<CustomerCredit> itemWriter(Resource outputResource) throws Exception { BeanWrapperFieldExtractor<CustomerCredit> fieldExtractor = new BeanWrapperFieldExtractor<>(); fieldExtractor.setNames(new String[] {"name", "credit"}); fieldExtractor.afterPropertiesSet(); FormatterLineAggregator<CustomerCredit> lineAggregator = new FormatterLineAggregator<>(); lineAggregator.setFormat("%-9s%-2.0f"); lineAggregator.setFieldExtractor(fieldExtractor); return new FlatFileItemWriterBuilder<CustomerCredit>() .name("customerCreditWriter") .resource(outputResource) .lineAggregator(lineAggregator) .build(); }
 

JSON Files

 
이번에는 JSON 파일을 읽고 쓰는 방법을 알아보겠습니다.
Jackson 또는 Gson 라이브러리를 사용하여 Java 객체와 JSON간 변환을 수행하여 읽고 쓸 수 있습니다.
 

JsonItemReader

 
JsonItemReader는 JSON 파일을 스트리밍 방식으로 읽어들이며, 각 JSON 객체를 Java 객체로 변환합니다. 이때, JSON 파싱과 바인딩은 JsonObjectReader 인터페이스의 구현체에 위임됩니다.
 

주요 구성 요소

  • Resource: 읽을 JSON 파일을 나타내는 Spring의 리소스 객체입니다.
  • JsonObjectReader<T>: JSON 객체를 Java 객체로 변환하는 역할을 합니다. 현재 Jackson과 Gson 기반의 두 가지 구현체가 제공됩니다:
    • JacksonJsonObjectReader
    • GsonJsonObjectReader
 

JsonItemReader Example

 
@Bean public JsonItemReader<Trade> jsonItemReader() { return new JsonItemReaderBuilder<Trade>() .jsonObjectReader(new JacksonJsonObjectReader<>(Trade.class)) .resource(new ClassPathResource("trades.json")) .name("tradeJsonItemReader") .build(); }
 
이 설정은 trades.json 파일에서 각 Trade 객체를 읽어들이는 JsonItemReader를 구성합니다.
 

JsonFileItemWriter

 
JsonFileItemWriter는 Java 객체를 JSON 형식으로 변환하여 파일에 기록합니다. 이때, 객체를 JSON 문자열로 변환하는 작업은 JsonObjectMarshaller 인터페이스의 구현체에 위임됩니다.
 

주요 구성 요소

  • WritableResource: 출력할 JSON 파일을 나타내는 Spring의 리소스 객체입니다.
  • JsonObjectMarshaller<T>: Java 객체를 JSON 문자열로 변환하는 역할을 합니다. 현재 Jackson과 Gson 기반의 두 가지 구현체가 제공됩니다:
    • JacksonJsonObjectMarshaller
    • GsonJsonObjectMarshaller
 

JsonFileItemWriter Example

 
@Bean public JsonFileItemWriter<Trade> jsonItemWriter() { return new JsonFileItemWriterBuilder<Trade>() .jsonObjectMarshaller(new JacksonJsonObjectMarshaller<>()) .resource(new FileSystemResource("output-trades.json")) .name("tradeJsonItemWriter") .build(); }
 
이 설정은 Trade 객체를 output-trades.json 파일에 JSON 형식으로 기록하는 JsonFileItemWriter를 구성합니다.
 

주의사항

 
Spring Batch에서 JsonItemReaderJsonFileItemWriter스레드 안전(thread-safe) 하지 않기 때문에 병렬 처리(parallel processing) 를 사용할 때 주의가 필요합니다.
 
안전한 병렬처리 해결 전략
 
  1. Partitioning 사용
      • 각 파티션이 서로 다른 JSON 파일을 읽고 쓰도록 설정하면, 스레드 간 충돌이 발생하지 않습니다.
  1. Step 단위로 인스턴스를 분리
      • 각 Step에서 JsonItemReader를 새로 생성하여 사용하면 스레드 간 공유 상태를 피할 수 있습니다.
      • 이 때에도 Scope("step") 또는 @StepScope 어노테이션을 사용할 수 있습니다.
 
파티셔닝 없이, 하나의 파일에 여러 스레드가 접근하는 방식은 스레드 안전하지 않다.
 

Database

 
Spring Batch에서 데이터베이스와 연동하여 데이터를 읽고 쓰는 방법은 크게 두가지로 나뉩니다.
  • 커서 기반
  • 페이징 기반
 

ItemReader

 
커서기반과 페이징 기반의 ItemReader를 살펴보겠습니다.

Cursor-based ItemReader

 
커서 기반 방식은 데이터베이스 커서를 사용하여 데이터를 순차적으로 읽어오는 방식입니다. 이 방식은 메모리 사용을 최소화하면서 대용량 데이터를 처리할 수 있다는 장점이 있습니다.
 
  • JdbcCursorItemReader: JDBC를 사용하여 데이터를 스트리밍 방식으로 읽습니다. ResultSet을 통해 데이터를 한 행씩 처리하며, 메모리에 전체 데이터를 로드하지 않기 때문에 메모리 효율성이 높습니다.
  • HibernateCursorItemReader: Hibernate를 사용하여 데이터를 커서 방식으로 읽습니다. Hibernate의 ScrollableResults를 활용하여 데이터를 순차적으로 처리합니다.
  • StoredProcedureItemReader: 저장 프로시저를 호출하여 결과를 커서 방식으로 읽습니다. 데이터베이스에 정의된 저장 프로시저를 통해 데이터를 가져옵니다.
 
주의사항
  • 커서 기반 방식은 데이터베이스 커넥션을 Step의 시작부터 끝까지 유지하므로, 장시간 커넥션 유지로 인한 리소스 소모나 잠금 문제에 주의해야 합니다.
 

Paging-based ItemReader

 
페이징 기반 방식은 데이터를 일정한 크기의 페이지로 나누어 읽는 방식입니다. 각 페이지는 독립적인 트랜잭션으로 처리되며, 커넥션 유지 시간이 짧다는 장점이 있습니다.
 
  • JdbcPagingItemReader: JDBC를 사용하여 데이터를 페이지 단위로 읽습니다. 쿼리에서 OFFSET과 LIMIT을 사용하여 데이터를 분할하여 가져옵니다.
  • HibernatePagingItemReader: JPA를 사용하여 데이터를 페이지 단위로 읽습니다. JPA의 페이징 기능을 활용하여 데이터를 분할하여 가져옵니다.
 
 

ItemWriter

 
  • JdbcBatchItemWriter: JDBC를 사용하여 데이터를 일괄적으로 삽입합니다. PreparedStatement를 사용하여 배치로 데이터를 처리하므로 성능이 우수합니다.
  • HibernateItemWriter: Hibernate를 사용하여 데이터를 저장합니다. Hibernate의 Session을 통해 엔티티를 저장하거나 갱신합니다.
 

마무리

 
지금까지 Spring Batch에서 다양한 방식으로 Item을 읽고 쓰는 방법에 대해 살펴보았습니다.
특히 데이터베이스 연동을 중심으로 커서 기반, 페이징 기반 Reader와 다양한 Writer에 대해 정리했고, 각각의 장단점도 함께 이해해보았습니다.
이 외에도 XML 파일, JSON 파일, Multi-Resource(Item) 방식 등 실무에서 자주 사용되는 다양한 Reader/Writer가 존재하며,
각 방식의 특성과 상황에 맞는 활용법은 Spring Batch 공식 문서를 참고하면 좋을 것 같습니다.
앞으로는 가장 활용도가 높은 Database 연동 방식에 대해 실습을 진행하고,
이를 직접 구성한 코드와 함께 포스팅할 예정입니다.
현재까지 Spring Batch 공식 문서의 약 절반 정도를 읽고 정리했으며,
남은 부분도 천천히 읽어가며 실습과 함께 블로그에 기록해나갈 계획입니다.
빨리 공부하고 실습을 해보고 싶습니다..
 

Reference

 
 
Share article

lushlife99