Spring Batch 2.0 시작하기

Similar documents
Spring Boot/JDBC JdbcTemplate/CRUD 예제

개발환경 교육교재

I T C o t e n s P r o v i d e r h t t p : / / w w w. h a n b i t b o o k. c o. k r

신림프로그래머_클린코드.key

Spring Data JPA Many To Many 양방향 관계 예제

PowerPoint Template

Microsoft PowerPoint - 04-UDP Programming.ppt

Spring Boot

JUNIT 실습및발표

12-file.key

Mobile Service > IAP > Android SDK [ ] IAP SDK TOAST SDK. IAP SDK. Android Studio IDE Android SDK Version (API Level 10). Name Reference V

PowerPoint 프레젠테이션

- JPA를사용하는경우의스프링설정파일에다음을기술한다. <bean id="entitymanagerfactory" class="org.springframework.orm.jpa.localentitymanagerfactorybean" p:persistenceunitname=

JAVA PROGRAMMING 실습 08.다형성

Microsoft PowerPoint - CSharp-10-예외처리

Connection 8 22 UniSQLConnection / / 9 3 UniSQL OID SET

교육2 ? 그림

@OneToOne(cascade = = "addr_id") private Addr addr; public Emp(String ename, Addr addr) { this.ename = ename; this.a

09-interface.key

2) 활동하기 활동개요 활동과정 [ 예제 10-1]main.xml 1 <LinearLayout xmlns:android=" 2 xmlns:tools="

제11장 프로세스와 쓰레드

Interstage5 SOAP서비스 설정 가이드

어댑터뷰

02 C h a p t e r Java

내장서버로사용. spring-boot-starter-data-jpa : Spring Data JPA 사용을위한설정 spring-boot-devtools : 개발자도구를제공, 이도구는응용프로그램개발모드에서유 용한데코드가변경된경우서버를자동으로다시시작하는일들을한다. spri

표준프레임워크로 구성된 컨텐츠를 솔루션에 적용하는 것에 문제가 없는지 확인

슬라이드 1

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

PowerPoint 프레젠테이션

* Factory class for query and DML clause creation * tiwe * */ public class JPAQueryFactory implements JPQLQueryFactory private f

1

rmi_박준용_final.PDF

NoSQL

PowerPoint Presentation

01-OOPConcepts(2).PDF

C# Programming Guide - Types

MasoJava4_Dongbin.PDF

ilist.add(new Integer(1))과 같이 사용하지 않고 ilist.add(1)과 같이 사용한 것은 자바 5.0에 추가된 기본 자료형과 해당 객체 자료 형과의 오토박싱/언박싱 기능을 사용한 것으로 오토박싱이란 자바 컴파일러가 객체를 요구하는 곳에 기본 자료형

교육자료

thesis

비긴쿡-자바 00앞부속

유니티 변수-함수.key

USER GUIDE

ch09

(Microsoft PowerPoint - java1-lecture11.ppt [\310\243\310\257 \270\360\265\345])

Cluster management software

04장

U.Tu System Application DW Service AGENDA 1. 개요 4. 솔루션 모음 1.1. 제안의 배경 및 목적 4.1. 고객정의 DW구축에 필요한 메타정보 생성 1.2. 제품 개요 4.2. 사전 변경 관리 1.3. 제품 특장점 4.3. 부품화형

Microsoft PowerPoint - Supplement-03-TCP Programming.ppt [호환 모드]

Microsoft PowerPoint - 03-TCP Programming.ppt

Index Process Specification Data Dictionary

Chap12

쉽게 풀어쓴 C 프로그래밍

A Hierarchical Approach to Interactive Motion Editing for Human-like Figures

5장.key

목차 BUG offline replicator 에서유효하지않은로그를읽을경우비정상종료할수있다... 3 BUG 각 partition 이서로다른 tablespace 를가지고, column type 이 CLOB 이며, 해당 table 을 truncate

Microsoft PowerPoint - Java7.pptx

목차 JEUS EJB Session Bean가이드 stateful session bean stateful sample 가이드 sample source 결과확인 http session에

<C0CCBCBCBFB52DC1A4B4EBBFF82DBCAEBBE7B3EDB9AE2D D382E687770>

PowerPoint Presentation

歯Writing_Enterprise_Applications_2_JunoYoon.PDF

쉽게 풀어쓴 C 프로그래밊

<property name="configlocation" value="classpath:/egovframework/sqlmap/example/sql-map-config.xml"/> <property name="datasource" ref="datasource2"/> *

API 매뉴얼

adfasdfasfdasfasfadf

목차 BUG DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4

Design Issues

Microsoft PowerPoint - java1-lab5-ImageProcessorTestOOP.pptx

Java XPath API (한글)

PowerPoint Presentation

파일로입출력하기II - 파일출력클래스중에는데이터를일정한형태로출력하는기능을가지고있다. - PrintWriter와 PrintStream을사용해서원하는형태로출력할수있다. - PrintStream은구버전으로가능하면 PrintWriter 클래스를사용한다. PrintWriter

슬라이드 1

ecorp-프로젝트제안서작성실무(양식3)

Eclipse 와 Firefox 를이용한 Javascript 개발 발표자 : 문경대 11 년 10 월 26 일수요일

No Slide Title

PowerPoint 프레젠테이션

( )부록

PowerPoint Presentation

Microsoft PowerPoint - RMI.ppt

JAVA PROGRAMMING 실습 05. 객체의 활용

[ 그림 8-1] XML 을이용한옵션메뉴설정방법 <menu> <item 항목ID" android:title=" 항목제목 "/> </menu> public boolean oncreateoptionsmenu(menu menu) { getme

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

ThisJava ..

Data Provisioning Services for mobile clients

untitled

JMF2_심빈구.PDF

<4D F736F F F696E74202D20C1A63236C0E520BED6C7C3B8B428B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

오버라이딩 (Overriding)

혼자서일을다하는 JSP. 이젠일을 Servlet 과나눠서한다. JSP와서블릿의표현적인차이 - JSP는 <html> 내에서자바를사용할수있는수단을제공한다. - 서블릿은자바내에서 <html> 을작성할수있는수단을제공한다. - JSP나서블릿으로만웹페이지를작성하면자바와다양한코드가

제8장 자바 GUI 프로그래밍 II

Network Programming

JMF3_심빈구.PDF

chap 5: Trees

untitled

Research & Technique Apache Tomcat RCE 취약점 (CVE ) 취약점개요 지난 4월 15일전세계적으로가장많이사용되는웹애플리케이션서버인 Apache Tomcat에서 RCE 취약점이공개되었다. CVE 취약점은 W

4장.문장

슬라이드 1

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

Web Application을 구성하는 패턴과 Spring ROO의 사례

PowerPoint 프레젠테이션

Transcription:

작성자 : 최한수 (cuteimp@gmail.com) 최종수정일 : 2009 년 6 월 22 일 본문서는 Spring Batch을학습하고자하는사람들을위하여 Sample Project를통해 Spring Batch 의기본적인이해와사용을돕는것을목적으로한다. Spring Batch 소개 Spring Batch 란? 우리가일반적으로알고있는 Batch라는것은일괄적으로어떠한작업을반복적으로처리하는것이다. 흔히이런 Batch Application을개발할때에는 I/O에대한처리부터내부적인로직의구현, 그리고 logging과같은부가적인기능들까지도모두개발자가직접개발하고이를어떠한스케줄러 (cron, quartz 등 ) 를통해서실행시키게된다. 보통대용량의 Batch Application들은매일적게는수만, 많게는수억건의 data를처리하게된다. 하지만여타의다른 Application(Web Application, Object/Relation Mapping) 들에비하여발전속도도느리고, 빠르게변화하는환경에적응하기가매우어려웠기때문에보다유연한시스템의개발과유지보수를위하여 Batch 프레임워크의필요성이대두되었다. Spring Batch는이러한대용량 Batch Application들을변화시키기위하여 Batch 작업에필요한기반작업들은모두 Framework에서관리하게끔하여편의성을제공하고 Spring을기반의 POJO(Plain Old Java Object) Programming을통하여재사용이가능하면서유연한 Application의개발이가능하도록도와주기위하여 Spring Source와 Accenture사가공동으로개발한 Batch Framework이다. Spring Batch Architecture Spring Batch는기본적으로다음과같은모습의 Architecture로구성되어있다. [ 그림 1 - Spring Batch Architecture, 출처 : Spring Batch Reference Chapter 1 ] 1 Last Updated : 2009 년 6 월 27 일

Batch Application은모든 Job이나사용자가필요에의해개발한코드가위치하고, Spring Batch Core는 job을실행하거나제어하기위한설정또는구현들이위치하게된다. 그리고마지막으로 Application과 Core에서사용하는 I/O나기본적인 Service등이 Batch Infrastructure에위치한다. 기존 Batch Application과 Spring Batch의차이점. 기존의 Batch Application들의특징은과거의웹 Application을 Model1 방식으로개발하던방식과같이모든것을하나의 Class 또는 Application안에서구현이되어있다는점이다. logging, 트랜잭션관리, 리소스관리 (I/O, Database Connection) 등에있어서도개발자마다차이가생기게되며이로인하여해당 Application의성능도천차만별이되고시간이지날수록해당 Application을개발한개발자조차 Application에대한유지보수에어려움을느끼게되는것이다. 게다가처리되어야하는작업을하나의단위로처리하는경우가많기때문에에러가발생했을때디버깅에어려움이많고작업을재시작하고자할때에도진행되어진부분이어디까지이며그이후부터작업을수행하기위해서도부가적인작업들을더수행해야하는어려움이있다. 이에반해 Spring Batch의경우에는기본적으로 Framework에서많은부분들을지원 (logging, 트랜잭션관리및리소스관리 (I/O, Database Connection) 등 ) 해주기때문에개발자는 Batch Application 개발에만집중을할수있게된다 (Separation of concern). 게다가이렇게프레임워크가지원해주는인프라덕분에개발된 Application의안정화에도도움이되며, 리소스를포함하는공통요소들에대한관리포인트도하나로합쳐지기때문에유지보수적인측면에서매우유리하다. 또한설정으로작업을여러단계로나눠서처리하기때문에에러가발생했을경우에디버깅이용이해지며, 실패한작업에대한재시작을하는경우에도손쉽게처리가가능하다. Spring Batch의기본적인구성및용어 Spring Batch에대한간략한구성은다음그림에서보는바와같다. 수행에필요한정보들은모두 Job repository에담고있고 Job Launcher를통하여 Job을실행시키게되며, 이 Job은여러개의 step으로구성되었으며각각의 step은 item reader/writer/processor를하나씩갖는다. [ 그림 2 - Spring Batch 의기본구성, 출처 : Spring Batch Reference Chapter 3 ] 2 Last Updated : 2009 년 6 월 27 일

Job, Step Job는 Batch에서처리해야하는 Process을의미한다. 매일저녁마다처리해야하는일마감업무가하나의 Job이되는샘이다. 이러한 Job은여러개의 Step으로구성이될수있으며, 이 Step이실제적으로수행되는작업의단위라고볼수있다. 즉, 일마감업무에는하루동안발생한거래내역을읽어들여처리하고, 관련된다른시스템들에자료를전송하거나갱신하는등의여러가지작업단계들이필요한데이러한작업단계하나하나가 Step인것이다. Execution Context 실행되고있는 Job(Job Instance) 과관련된정보 (read count, write count, skip count, 재시작횟수등의통계정보 ) 들을저장하거나조회할수있는일종의메모리로, 우리가흔히알고있는 Web Application에서사용되는 Session의일종이라고생각하면된다. Job Launcher Job Parameter(Job을실행할떄필요한매개변수 ) 를포함하여 Job을실행시키는실행기이다. Job Repository 수행되는 Job에대한정보를담고있는저장소로써어떠한 Job이언제수행되었고, 언제끝났으며, 몇번이실행되었고실행에대한결과가어떤지등의 Batch수행과관련된모든 meta data가저장되어있다. Item Reader Step안에서 File 또는 DB등에서 Item을읽어들인다.. Item Writer Step안에서 File 또는 DB등으로 Item을저장한다. Item Processor Item reader에서읽어들인 Item에대하여필요한로직처리작업을수행한다. Chunk 하나의 Transaction안에서처리할 Item의덩어리. 즉 chunk size가 10이라면하나의 transaction안에서 10개의 item에대한처리를하고 commit을하게되는것이다. Spring Batch 2.0의새로운점 Spring Batch는현재 2.0 정식버전이배포된상태이며, 최신버전인 2.0은 1.x 버전과의하위호환성을갖지않으며많은변경사항이있으나개인적으로는다음 3가지변화에주목하고있다. Chunk oriented processing 3 Last Updated : 2009 년 6 월 27 일

기존 Spring Batch 1.x에서는 Item을기반으로작업을처리해왔다. 이 Item이라는것은하나의 Data라고생각하면된다. 다음그림에서와같이 Item 기반의처리는 Item을읽고, 처리하고쓰는것이하나의단위였다면, chunk 기반의처리는지정한크기만큼 Item을읽고, 처리한후이결과를 list의형태로가지고있다가한번에쓰는방식인것이다. 이로인하여리소스관리측면에서이점을가져올수있게되었다. [ 그림 3 - Spring Batch Item 처리방식의변화, 출처 : Spring Batch Reference Chapter 2 ] XML Namespace 기존의 1.x에서는 XML 설정시모든설정항목이오로지 bean으로설정되었기때문에실제 job, step의구성이나사용하는 item reader/writer에대한파악을위해서는 bean id와 property값들을기초로하여분석해야알수있었지만, 2.0에서 XML Namespace가추가되면서 XML 설정상에서 Job과 Step과의관계를명시적으로확인할수있으며, 사용하고있는 item reader/writer의파악도좀더손쉬워졌다. XML Namespace의설정은다음과같이할수있으며굵게표시된부분이 batch의 namespace와 schema이다. <beans:beans xmlns="http://www.springframework.org/schema/batch" xmlns:beans=http://www.springframework.org/schema/beans xmlns:aop=http://www.springframework.org/schema/aop xmlns:tx=http://www.springframework.org/schema/tx xmlns:p=http://www.springframework.org/schema/p xmlns:xsi=http://www.w3.org/2001/xmlschema-instance xsi:schemalocation= http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd 4 Last Updated : 2009 년 6 월 27 일

http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> </beans:beans> Conditional Step Execution Spring Batch 1.x의경우에는모든 Step의실행이순차적으로이루어졌어야했다. 예외상황이발생하게되는경우에는그냥 skip하여다음 item을처리하거나해당 job의 fail처리를 Listener나 Item Processor를통하여약간의제어는가능하긴했지만실제적으로는거의 Job을재시작하여다시수행하였었다. 하지만 2.0에서부터추가된 Control flow를통하면현재진행중인작업의 ExitStatus( 처리결과상태 ) 에따라서수행할다음 Step을지정하거나우회된 Step으로진행또는 Job을중지시키는것도가능하게되었다. [ 그림 4 - Step 제어방식의변화, 출처 : Spring Batch Reference Chapter 2 ] Sample Project Sample Project의개요 Sample Project는간단한 Application을통하여 Job, Step, Item Reader/Writer등의설정방법과몇가지 in/out 유형별샘플을보여주기위해만들어졌다. Sample Project의간단한흐름은다음과같다. 1. 구분자를포함하는파일 (CSV) 에서고객정보를읽어들인후 Database에저장한다.(customerCsvLoad) 2. 고정된길이로정의되어있는파일에서고객의정보를읽어들인후 Database에저장한다.(customerFixedLoad) 3. Database에저장되어있는고객정보를읽어들인후통계정보를다시 Database에저 5 Last Updated : 2009 년 6 월 27 일

장한다.(customerSummarization) 4. Database에저장되어있는전체고객정보를구분자를포함하는파일로저장한다.(exportCustomer) Sample Project의실행 Sample Project는실행시에읽어들여야하는파일 (input data) 과 Database에관한정보는모두설정되어있기때문에 test패키지에존재하는 CustomerJobFunctionalTests를 run as Junit Test로실행시키기만하면된다. Input 파일의경우에는 resources/data/input에존재하며 customerjob.xml 설정상의 customerjobproperties bean내에서사용할파일의이름에대하여정의되어있다. 필요하다면해당파일명을변경하고실제 resources/data/input내의파일의이름로변경해주면된다. 만약 hsql이아닌다른 database를사용하여 sample project를수행하고싶다면, data-sourcecontext.xml에설정되어있는 overrideproperties bean의 location 속성의값을수정하면된다. 현재는시스템의기본설정값으로 hsql을정의해두었고이설정에의해서 resources/batchhsql.properties 파일의정보를읽어들이게되어있다. 따라서 location 속성자체를수정하거나 environment bean의 defaultvalue 속성을수정하고, 실제 property 파일을원하는위치에저장해두면해당값들을읽어들일수있게된다. Sample Project 의이해 Job, step 설정 Job에대한설정은앞서선언한 namespace가있다면다음과같이 <job> 태그를사용하여정의할수있다. 이예제는앞서설명한대로총 4개의 step으로구성이되어있는 job이다. 각각의 step에는 item reader/writer의설정이있으며 next속성을이용하여다음에실행되어야하는 step 을지정하고, 공통적으로모든 step의 commit 주기를통일하기위하여 commit-interval은따로관리하도록했다. Step의 control flow에대한내용은뒷부분에서다시다루기로한다. 이중첫번째 step인 customercsvload만을이글에서는보여주도록한다. <job id="customerjob"> <step id="customercsvload"> <tasklet> <chunk reader="customercsvreader" writer="customerdbwriter" commit-interval="${job.commit.interval" /> </tasklet> </step> </job> 6 Last Updated : 2009년 6월 27일

예제에서볼수있듯이 job안에 step이설정되고 step은내부적으로 tasklet 형태로선언된다. 처리할단위로묶어서 (chunk) reader와 writer에대한설정을추가한다. reader/writer의경우에는별도의 bean으로설정하여 reference하여사용한다. Item Reader, Writer 설정앞서의 job,step 설정에서는 item reader/writer의설정은단순히 reader/writer의 id값만을설정하는것처럼보이지만실제로는 reader/writer도당연히 bean으로설정을해주어야한다. 기본적으로 sample에서사용된 item reader는 FlatFileItemReader와 JdbcCursorItemReader 두가지이다. 이름에서유추할수있듯이전자는파일에서 item을읽을때사용하는것이고후자는 Database 에서 item을읽을때사용하는것이다. Spring Batch에서제공하는기본적인 reader/writer에대한간략한표는첨부자료에서확인할수있다. 우선파일로부터 item을읽어들이는 FlatItemReader부터살펴보자. 이 reader의경우에다음과같은순서로파일로부터 item을얻어낸다. 파일에있는하나의라인을 LineMapper를이용하여 fieldset으로변환한다. 이때 LineTokenizer를통하여구분자또는고정길이설정을통해하나의 row를 fieldset으로분해하는것이다. 이렇게분해된 fieldset은 fieldsetmapper를통하여미리설정해둔 Domain Object와 Mapping 하게되는것이다. 즉실제적으로파일에서 item을읽어들이는작업은하나의 ItemReader를사용하되 LineTokenizer의종류에따라서구분자방식또는고정길이방식을처리할수있게된다. [ 그림 5 - File 기반의 Item Reader 의작동방식 ] Sample Project에서구분자를이용한 ItemReader의설정은다음과같다. FlatFileItemReader를이용하며, 읽어들여야할파일을 resource property로정의하고 linemapper는기본제공되는 DefaultLineMapper를사용했다. DelimitedLineTokenizer를사용하여기본구분자인, 를이용하여읽어들인하나의 line을 fieldset으로변경한다. field들에대한이름을 names property로설정해주고 fieldset과 object와의 mapping 설정을해둔 CustomerFieldSetMapper를추가하여주었다. <beans:bean id="customercsvreader" class="org.springframework.batch.item.file.flatfileitemreader"> <beans:property name="resource" 7 Last Updated : 2009년 6월 27일

value="classpath:data/input/${customer.file.csv.name" /> <beans:property name="linemapper"> <beans:bean class="org.springframework.batch.item.file.mapping.defaultlinemapper"> <beans:property name="linetokenizer"> <beans:bean class="org.springframework.batch.item.file.transform.delimitedl inetokenizer"> <beans:property name="names" value="name,age,gender,email,contact,memo,joinda te" /> <beans:property name="fieldsetmapper"> <beans:bean class="net.evilimp.batch.sample.domain.internal.customerfie ldsetmapper" /> FieldsetMapper는다음과같은형태를띄고있다. 굵게표시된부분에서볼수있듯이사용하고자하는 domain object에 fieldset의각 field를읽어서 mapping 해주게된다. package net.evilimp.batch.sample.domain.internal; import net.evilimp.batch.sample.domain.customer; import org.springframework.batch.item.file.mapping.fieldsetmapper; import org.springframework.batch.item.file.transform.fieldset; public class CustomerFieldSetMapper implements FieldSetMapper<Customer> { @Override public Customer mapfieldset(fieldset fs) { // fieldset이 null인경우에는 null을반환한다. if (fs == null) { return null; 8 Last Updated : 2009 년 6 월 27 일

Customer customer = new Customer(); customer.setname(fs.readstring("name")); customer.setage(fs.readint("age")); customer.setgender(fs.readstring("gender")); customer.setemail(fs.readstring("email")); customer.setcontact(fs.readstring("contact")); customer.setmemo(fs.readstring("memo")); customer.setjoindate(fs.readstring("joindate")); return customer; 고정길이방식의 ItemReader의경우에는앞서보인구분자를포함하는 ItemReader와거의모든것이동일하고 linetokenizer설정만이다르다. <beans:bean id="customerfixedreader" class="org.springframework.batch.item.file.flatfileitemreader"> <beans:property name="resource" value="classpath:data/input/${customer.file.fixed.name" /> <beans:property name="linemapper"> <beans:bean class="org.springframework.batch.item.file.mapping.defaultlinemapper"> <beans:property name="linetokenizer" ref="customertokenizer" /> <beans:property name="fieldsetmapper"> <beans:bean class="net.evilimp.batch.sample.domain.internal.customerfields etmapper" /> <beans:bean id="customertokenizer" class="org.springframework.batch.item.file.transform.fixedlengthtokenizer"> <beans:property name="names" value="name,age,gender,email,contact,joindate,memo" /> 9 Last Updated : 2009 년 6 월 27 일

<beans:property name="columns" value="1-10, 11-12, 13-13, 14-43, 44-54, 55-62, 63-66" /> 설정에서볼수있듯이 linetokenizer를따로선언해서사용하는데이는 bean설정을따로빼도되는것을보여주기위함이고구분자를사용하는 ItemReader와마찬가지로 ItemReader내에바로설정해도무방하다. FixedLengthTokenizer를사용하여하나의라인에대해서각각의 field에대한이름과길이를지정해주면된다. FileWriter의경우에는이와반대의작업이필요한다. 객체를파일에쓰기위해서는하나의 String 으로변경해주는작업을해주어야하는데이작업을하는것이 LineAggregator이다. LineAggregator는객체에서필드들을추출하여구분자를추가하거나고정길이와비교하여부족한공간을공백으로채워주는작업을수행한다. [ 그림 6 - File 기반의 Item Writer 의작동방식 ] 앞서 FileItemReader와는조금다른모습이지만실제적으로는거의동일한모습을보인다. 다만파일에 item을쓰기위한실제적인일을처리하는 customercsvwriter가있고그것을감싸면서 ItemWriter를구현한 customerwriter로구분이되어처리된다. <beans:bean id="customerwriter" class="net.evilimp.batch.sample.domain.internal.customerfilewriter"> <beans:property name="dao" ref="customercsvwriter" /> <beans:bean id="customercsvwriter" class="net.evilimp.batch.sample.domain.internal.flatfilecustomerdao"> <beans:property name="itemwriter"> <beans:bean id="customerflatfileoutputsource" class="org.springframework.batch.item.file.flatfileitemwriter"> <beans:property name="resource" value="file:resources/data/output/${customer.file.csv.name" /> <beans:property name="lineaggregator"> <beans:bean class="org.springframework.batch.item.file.transform.passthroug hlineaggregator" /> 10 Last Updated : 2009년 6월 27일

다음의실제 Class 파일에서볼수있듯이 CustomerFileWriter는단지 ItemWriter를구현하여인터페이스를맞춰주는역할을한다. package net.evilimp.batch.sample.domain.internal; import java.util.list; import net.evilimp.batch.sample.domain.customer; import net.evilimp.batch.sample.domain.customerdao; import org.springframework.batch.item.itemwriter; public class CustomerFileWriter implements ItemWriter<Customer> { private CustomerDao dao; public void setdao(customerdao customerdao) { this.dao = customerdao; public void write(list<? extends Customer> customers) throws Exception { for (Customer customer : customers) { dao.write(customer); 실제적으로파일에쓰는작업을하는 FlatFileCustomerDao는다음과같다. 굵게표시된메소드들을보면파일에 write 하기위해서먼저파일의 stream을 open 해주는작업을수행하게되며, 모든작업이종료될때자동으로호출되는 destroy 메소드내에서 close 메소드를호출하여파일을닫아주게된다. package net.evilimp.batch.sample.domain.internal; import java.util.collections; import org.springframework.batch.item.executioncontext; 11 Last Updated : 2009 년 6 월 27 일

import org.springframework.batch.item.itemstream; import org.springframework.batch.item.itemwriter; import org.springframework.beans.factory.disposablebean; import net.evilimp.batch.sample.domain.customer; import net.evilimp.batch.sample.domain.customerdao; public class FlatFileCustomerDao implements CustomerDao, DisposableBean { private ItemWriter<String> itemwriter; private String separator = ","; private volatile boolean opened = false; @Override public void write(customer customer) throws Exception { if (!opened) { open(new ExecutionContext()); String line = "" + customer.getname() + separator + customer.getage() + separator + customer.getgender() + separator + customer.getemail() + separator + customer.getcontact() + separator + customer.getmemo() + separator + customer.getjoindate(); itemwriter.write(collections.singletonlist(line)); public void setseparator(string separator) { this.separator = separator; public void setitemwriter(itemwriter<string> itemwriter) { this.itemwriter = itemwriter; public void open(executioncontext executioncontext) throws Exception { if (itemwriter instanceof ItemStream) { ((ItemStream) itemwriter).open(executioncontext); 12 Last Updated : 2009 년 6 월 27 일

opened = true; public void close() throws Exception { if (itemwriter instanceof ItemStream) { ((ItemStream) itemwriter).close(); @Override public void destroy() throws Exception { close(); 앞서 File과관련된 reader/writer와는다르게 Database에서 item을읽어들이는 ItemReader의방식은오히려간단하다. 다음과같이 Database에서조회된 ResultSet을 RowMapper를이용하여 Domain Object와 Mapping 한다. [ 그림 7 - Database 기반의 Item Reader 의작동방식 ] Sample Project에서는기본적으로 Spring Jdbc를이용하기위해 JdbcCursorItemReader를사용한다. 그리고 result의 row와 object와의 mapping을위하여 CustomerMapper를사용한다. 실행하고자하는 sql문을설정해주면된다. <beans:bean id="customerdbreader" class="org.springframework.batch.item.database.jdbccursoritemreader"> <beans:property name="datasource" ref="datasource" /> <beans:property name="rowmapper"> <beans:bean class="net.evilimp.batch.sample.domain.internal.customermapper" /> <beans:property name="sql"> <beans:value> SELECT idx, name, age, gender, email, contact, memo, joindate FROM CUSTOMER 13 Last Updated : 2009 년 6 월 27 일

</beans:value> 반대로 Database에 write를하기위해서는 Object의값들을바로 SQL Parameter로 mapping이가능하기때문에따로중간에변형하는작업이필요없다. 실제 XML상의설정으로도 bean을선언하는것외에따로작업해주는것은없고클래스내에서 sql에 object를 bind 하는작업만이필요하다. <beans:bean id="customerdbwriter" class="net.evilimp.batch.sample.domain.internal.jdbccustomerdao"> <beans:property name="datasource" ref="datasource" /> Conditional Step Execution 설정 Step을실행하는과정에서특정한조건이나상태에따라서해당 step의실행을중지시키거나다음에실행되어야하는 step이변경되어야하는경우가발생할수있다. Spring Batch는이러한상황을 Step의 ExitStatus의값으로판단을하여처리를하게된다. 앞서의 job, step의예제에서보면 2가지의 step제어방법이나온다. 이 2가지방법은원리는동일하지만사용자가직접제어를하는지 Framework에서제어를하는지의차이점만있다. 우선 Framework에서제어를하는경우에는다음과같이 exitstatus에따른제어를해줄수있다. <next on="*" to="customersummarization" /> <next on="completed WITH SKIPS" to="fixederrorprint" /> <fail on="failed" exit-code="failed"/> Next의경우에는 property중해당조건을수행하기위한 exitstatus를설정해주고 to를통하여다음에실행되어야하는 step의 id를선언해주면되고, job 자체를실패로간주하기위하여사용되는 fail의경우에는 on property에마찬가지로 exitstatus를설정하고 exit-code에전달하고자는 exitstatus를선언한다. 예제는없지만 stop의경우에는 next와마찬가지로 on property에 exitstatus를설정하고 restart property에다음번에해당 job이재시작되는경우에수행할 step의 id를설정해주면된다. End의경우에 on property에오는 exitstatus에따라서해당 job을종료시키게된다. 방금설명한방법의경우간단하게 step의흐름을제어할수있지만개발자가임의로 step의제어를하고자경우에는다음과같이 decider를구현하여사용하여야한다. 이 decider의경우해당 setp이실패하지않았으면서 skipcount가 2 이상인경우에는 exitstatus를 "COMPLETED WITH SKIPS" 로변경하여반환하고아닌경우에는 COMPLETED 를반환한다. <decision id="skipcheckingdecision" decider="skipcheckingdecider"> 14 Last Updated : 2009 년 6 월 27 일

<next on="*" to="customerfixedload" /> <next on="completed WITH SKIPS" to="csverrorprint" /> <fail on="failed" exit-code="failed"/> </decision> import org.springframework.batch.core.exitstatus; import org.springframework.batch.core.jobexecution; import org.springframework.batch.core.stepexecution; import org.springframework.batch.core.job.flow.flowexecutionstatus; import org.springframework.batch.core.job.flow.jobexecutiondecider; public class SkipCheckingDecider implements JobExecutionDecider { public FlowExecutionStatus decide(jobexecution jobexecution, StepExecution stepexecution) { if (!stepexecution.getexitstatus().getexitcode().equals( ExitStatus.FAILED.getExitCode()) && stepexecution.getskipcount() > 2) { return new FlowExecutionStatus("COMPLETED WITH SKIPS"); else { return new FlowExecutionStatus(ExitStatus.COMPLETED.getExitCode()); 맺음말여기까지간단한 sample project를통하여 Spring Batch에대한소개를했다. Spring Batch의모든것을보여주기에역부족인글이지만기존버전에비하여좀더간략하고명시적인설정을통하여수행하고자하는 job에대한이해와 step에대한구성을효율적으로할수있음을보여주었으며, 새롭게등장한 step의실행제어까지의내용을다루었다. 이를통하여기존의 batch application과 Spring Batch를사용할때와의다른모습들을볼수있었을것이며, Spring Batch에대한기본적인이해에도움이되었을것이다. 보다많은정보가필요하면레퍼런스문서와 Spring Source의포럼을통하여얻을수있다. 국내자료로는 KSUG의다음글을참조하면된다. 참고자료. 15 Last Updated : 2009 년 6 월 27 일

1. Spring Source, Spring Batch Reference, 2009 첨부자료 1. Spring Batch 에서기본적으로제공되는 Item Reader/Writer Reader 이름 설 명 FlatFileItemReader 구분자 (csv 와같은 ) 를갖는파일또는고정길이파일로부터 item 을읽어들인다. MultiResourceItemReader 여러개의파일로부터 item 을읽어들인다. JdbcCursorItemReader Jdbc 를이용하여 cursor 방식으로 DB 로부터 item 을읽어들인다. JdbcPagingItemReader Jdbc 를이용하여 paging 방식으로 DB 로부터 item 을읽어들인다. Hibernate 를이용하여 cursor 방식으로 DB 로부터 item 을 HIbernateCursorItemReader 읽어들인다. IbatisPagingItemReader Ibatis 를이용하여 paging 방식으로 DB 로부터 item 을읽어들인다. JpaPagingItemReader Jpa 를이용하여 paging 방식으로 DB 로부터 item 을읽어들인다. StaxEventItemReader XML 파일로부터 item 을읽어들인다. [ 표 1 Spring Batch에서제공되는 Item Reader ] Writer 이름 설 명 FlatFileItemWriter 구분자 (csv 와같은 ) 를갖는파일또는고정길이파일로 item 을 Write 한다. MultiResourceItemWriter 여러개의파일로 item 을 Write 한다. JdbcBatchItemWriter Jdbc 를이용하여 batchupdate 의형태로 DB 로 item 을 Write 한다. HibernateItemWriter Hibernate 를이용하여 DB 로 item 을 Write 한다. IbatisBatchWriter Ibatis 를이용하여 DB 로 item 을 Write 한다. StaxEventItemWriter XML 파일로 item 을 Write 한다. [ 표 2 Spring Batch에서제공되는 Item Writer ] * 샘플프로젝트의다운로드는다음의 URL에서가능하다. [Download] * 본문서는지속적인갱신이발생할수있다. 16 Last Updated : 2009 년 6 월 27 일