목차 >> Spring Batch 
+- Spring Batch 란  
----+- xmlns:batch 네임스페이스  
----+- ItemReader & ItemWriter  
+- Glue Batch  
+- Glue ItemReader & ItemWriter  
----+- GlueCursorItemReader & GlueJdbcBatchItemWriter  
----+- GlueDefaultItemReader & GlueDefaultItemWriter  
----+- GlueCompositeCursorReader & GlueCompositeFileReader  
+- Glue JobLauncher  
----+- GlueQuartzJobLauncher  
----+- GlueJobLaunch

19장 Spring Batch

Glue Framework에서 제공하는 Glue Batch 모듈은 Spring Batch를 기반으로 합니다. Glue Batch 모듈의 원활한 적용을 위해서는 Spring Batch 에 대한 기본적인 이해를 전제로 합니다.

이번 장에서는 Spring Batch 를 조금 다루고 있으나, 보다 자세한 것은 Spring Batch 사이트를 참고하시기 바랍니다.

Spring Batch 란

Batch 어플리케이션은 사람의 도움없이 데이터를 자동으로 처리하기 때문에 견고하고 믿을 수 있어야 합니다.
그리고, Batch 어플리케이션이 처리하는 데이터의 양이 많을수록 처리시간도 길어지지만, 처리시간은 특정 시간 내로 제한되는 경우가 많기 때문에 Batch 어플리케이션의 수행 성능도 고려되어야 합니다.

Spring Batch 프로젝트는 Accenture 사의 현장 경험과 SpringSource 사의 기술력이 합쳐져서 탄생되었으며, Spring Batch의 목표는 Batch 어플리케이션의 요구사항을 효과적으로 해결하기 위한 Batch 기반 오픈소스 Framework을 제공하는 것입니다.

한가지 주의해야 할 점은 Spring Batch는 Scheduler가 아니라는 것입니다.
Spring Batch는 Batch Job 을 관리하지만 스케쥴링에 따라 Job을 구동하는 기능은 지원하지 않습니다.
Spring Batch는 Quartz 나 cron 과 같은 전용 Scheduler들에게 이런 역할을 하도록 하였습니다.
Scheduler는 일련의 연속된 Job을 실행시키기도 합니다. 예를 들어 Job A를 실행하고 Job A 가 설공적으로 끝나면 Job B를 실행하고 Job A가 실패하면 Job C를 실행시키기도 합니다.
Spring Batch는 이런 일련의 절차를 자체적으로 조정할 수 있습니다. Spring Batch의 Job 은 여러 개의 Step 으로 설정되고 각 Step의 실행순서는 스프링 배치 XML 을 사용해서 쉽게 설정할 수 있습니다.

Spring Batch 의 주요 기능들을 정리하면 아래와 같습니다(한국스프링사용자모임을 참고하였습니다).

  • 각종 읽기와 쓰기 기능의 구성요소를 같은 인터페이스들로 추상화 시키고 있고, 그에 맞는 기본 구현 클래스를 제공한다.
  • 대용량 조회 처리를 위해서 커서기반이나 Driving query기반의 조회방식을 지원한다.
  • Stream방식의 파일 처리를 더욱 편리하게 할 수 있는 API를 제공한다.
  • 배치에 적합한 트랜잭션 처리를 위해 주기적인 commit방식을 지원한다.
  • 배치작업의 재시도, 재시작, 건너뛰기 등의 정책을 설정으로 적용할 수 있다.
  • 유연한 Exception 처리를 할 수 있다.
  • 각종 이벤트 처리가 가능하다.
  • Commit 개수, Rollback 개수, 재시도 횟수 등 배치실행 통계 정보를 제공한다.
  • 다양한 실행방법을 선택할 수 있다.
  • 추가 코딩 없이 설정만으로 기존 모듈 활용의 가능하다.
  • myBatis를 사용해서 DB접근모듈을 개발할 수 있다.
  • Validation 기능을 SpringValidator와 apache commons validator 를 사용해서 구현할 수 있다.

Spring Batch 의 구성 요소를 정리하면 다음과 같습니다.

  • Job : Batch 처리를 의미하는 어플리케이션 컴포넌트

  • JobInstance : 논리적인 Job 실행.
    JobInstance = Job + JobParameter

  • JobExecution : 단 한 번 시도되는 Job 실행을 의미.
    시작시간, 종료시간, 상태(시작됨,완료,실패), 종료상태의 속성을 가짐

  • JobParameter : Batch Job을 시작하는데 사용하는 파라미터의 집합으로 Job이 실행되는 동안에 Job을 식별하거나 Job에서 참조하는 데이터로 사용됨.

    그림 : 출처 - http://bcho.tistory.com/763
  • Step : Batch job을 구성하는 독립적인 하나의 단계.
    Job은 하나이상의 step으로 구성됨.
    실제 Batch 처리 과정을 정의하고, 제어하는데 필요한 모든 정보를 포함함.

    • Step Execution : 하나의 step을 실행하는 한번의 시도.
      시작시간, 종료시간, 상태, 종료상태, commitCount, itemCount 의 속성을 가짐.

  • Tasklet : Tasklet 은 Step 내부의 트랜잭션 또는 반복될 수 있는 처리작업을 의미.
    개발자들은 Tasklet 인터페이스를 직접 구현해서 사용하거나 스프링 배치가 제공하는 구현체를 사용할 수도 있음.

  • Chunk : 하나의 Transaction안에서 처리할 Item의 덩어리.
    chunk size가 10이라면 하나의 transaction안에서 10개의 item에 대한 처리를 하고 commit을 하게 됨.

    • Item : 처리할 데이터의 가장 작은 구성 요소.(예: 파일의 한 줄, DB의 한 Row, Xml의 특정 element )
    • ItemReader : Step안에서 File 또는 DB등에서 Item을 읽음. 더 이상 읽어올 Item이 없을 때에는 read()메소드에서 null값을 반환. 그 전까지는 순차적인 값을 리턴
    • ItemWriter : Step안에서 File 또는 DB등으로 Item을 저장.
    • Item Processor : Item reader에서 읽어 들인 Item에 대하여 필요한 로직 처리 수행.
  • Job Launcher : Job 을 실행시키는 역할을 갖음.

  • JobRepository : 수행되는 Job에 대한 정보를 담고 있는 저장소.
    어떠한 Job이 언제 수행되었고, 언제 끝났으며, 몇 번이 실행되었고 실행에 대한 결과가 어떤지 등의 Batch 수행과 관련된 모든 meta data가 저장됨.

    그림 : 출처 - http://docs.spring.io/spring-batch-old/1.1.x/spring-batch-docs/reference/html-single

xmlns:batch 네임스페이스

Spring 에서는 Spring Batch 설정 전용 XML 네임스페이스를 제공합니다.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:batch="http://www.springframework.org/schema/batch"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                        http://www.springframework.org/schema/batch
                        http://www.springframework.org/schema/batch/spring-batch-3.0.xsd">

    <batch:job-repository />
    <bean id="dataSource" . . ./>
    <bean id="transactionManager" . . ./>

    <batch:job id="job">
        <batch:step id="step-1" next="step-2">
            <batch:tasklet ref="tasklet" />
        </batch:step>
        <batch:step id="step-2">
            <batch:tasklet>
                <batch:chunk reader="reader" processor="bizProcessor" writer="writer" />
            </batch:tasklet>
        </batch:step>
    </batch:job>
    <bean id="tasklet" . . ./>
    <bean id="bizProcessor" . . ./>
    <bean id="reader" . . ./>
    <bean id="writer" . . ./>
</beans>

batch 네임스페이스를 통해 사용할 수 있는 주요 태그는 다음과 같습니다.

  1. job : 배치 job 을 설정한다.

    스프링 배치로 배치 어플리케이션을 구현할 경우 최상위 엔티티는 <batch:job> 이며, 배치 처리를 정의할 때 가장 먼저 설정하는 엔티티입니다.
    batch 네임스페이스의 job은 다음과 같은 속성을 갖습니다.

    • id : job 식별자
    • restartable : 스프링 배치가 job 을 재실행할 수 있는지 여부를 지정함. 디폴트는 true
    • incrementer : Job 파라미터 값을 설정하기 위해 사용되는 엔티티에 대한 레퍼런스.
      이 엔티티는 JobOperator 인터페이스의 startNextInstance 메소드를 사용해서 배치 job 을 실행시키는 경우에 필요합니다.
      <batch:job id="samplejob" incrementer="customIncrementer">
          . . .
      </batch:job>
      <bean id="customIncrementer" class=". . ."/>
      
    • abstract : job 설정이 추상레벨인지 여부를 지정함.
      true 로 지정되면 이 job 설정이 다른 job 설정을 위한 상위 설정임을 의미합니다.
    • parent : 설정하는 job 의 상위 job 설정.
    • job-repository : 설정하는 job 을 위한 job repository 를 지정한다. 아무것도 설정하지 않을 경우 jobRepository 를 기본값으로 한다.
  2. step : 배치 step 을 설정한다.

    <batch:step> 이란 job 의 각 단계를 나타냅니다. job 내부의 step 들은 job 이 수행해야 하는 일련의 처리 절차를 의미합니다.
    batch 네임스페이스의 step은 다음과 같은 속성을 갖습니다.

    • next : 다음으로 수행할 step
      <batch:job id="samplejob">
          <batch:step id="sample1" next=" sample2">
              . . .
          </batch:step>
          <batch:step id="sample2">
              . . .
          </batch:step>
      </batch:job>
      
    • parent : 상위 step 설정
    • abstract : step 설정이 추상레벨인지 여부를 지정.
      true 로 지정되면 이 step 설정이 다른 step 설정을 위한 상위 설정임을 의미합니다
  3. tasklet : step 내에서 사용되는 tasklet 을 설정한다.

    <batch:tasklet> 은 각 step에서 수행되는 로직입니다. 개발자가 Custom Logic을 만들 수도 있으나, 또는 보통 Batch의 경우 데이타를 ETL (Extract, Transform, Loading) 하는 형태이기 때문에, Spring Batch에서 미리 정의해놓은 Reader, Processor, Writer Interface를 사용할 수 있습니다.

    • ItermReader - 데이타를 읽는 컴포넌트
    • ItemProcessor - 읽은 이타를 처리
    • ItemWriter - 처리한 데이타를 저장
    <batch:job id="samplejob">
        <batch:step id="sample1" next=" sample2">
            <batch:tasklet ref="customtasklet" />
        </batch:step>
        <batch:step id="sample2">
            <batch:tasklet>
                <batch:chunk reader="itemReader" writer="itemWriter" processor="ItemProcessor" commit-interval="500"/>
            </batch:tasklet>
        </batch:step>
    </batch:job>
    <bean id="customtasklet" . . . />
    
  4. chunk : step 내에서 사용되는 chunk 를 설정한다.

    <batch:job id="samplejob">
        <batch:step id="sample2">
            <batch:tasklet>
                <batch:chunk reader="itemReader" writer="itemWriter" processor="itemProcessor" commit-interval="500"/>
            </batch:tasklet>
        </batch:step>
    </batch:job>
    <bean id="itemReader" . . . />
    <bean id="itemWriter" . . . />
    <bean id="itemProcessor" . . . />
    
  5. job-repository : 메타데이터를 위한 job repository 를 설정한다.

    <batch:job-repository id="jobRepository" data-source="dataSource" transaction-manager="transactionManager"/>
    <bean id="dataSource" . . ./>
    <bean id="transactionManager" . . ./>
    
    <batch:job id="samplejob" job-repository="jobRepository">
        . . .
    </batch:job>
    

ItemReader & ItemWriter

Spring Batch에서는 Item을 읽고 쓰는 API들을 ItemReader, ItemWriter 인터페이스로 추상화해서 제공하고 있습니다.

  • ItemReader

    ItemReader는 여러 종류의 데이터 타입을 입력 받을 수 있습니다.
    기본적인 ItemReader 인터페이스는 아래와 같다.

    public interface ItemReader<T> {
        T read() throws Exception, UnexpectedInputException, ParseException;
    }
    

    read() 메소드는 ItemReader의 필수적인 메소드이며 결과값으로 하나의 item을 반환하고 더이상 반환할 item이 없을 경우 null을 반환합니다.
    item은 플랫 파일에서의 한 라인, 데이터베이스에서의 한 행, XML 파일에서의 엘리먼트를 나타냅니다.

  • ItemWriter

    ItemWriter의 기능은 ItemReader와 유사하지만 정반대의 동작을 합니다.
    기본적인 ItemWriter 인터페이스는 아래와 같다.

    public interface ItemWriter<T> {
        void write(List<? extends T> items) throws Exception;
    }
    

    write() 메소드는 ItemWriter의 필수적인 메소드이며 인자로 건넨 객체가 열려 있는 동안 쓰기 작업을 시도합니다.

Glue Batch

Glue에서는 ApplicationContext 설정을 통해서 Spring Batch기능을 사용할 수 있습니다.
설정하는 XML파일은 Glue에서 기본으로 사용하는 applicationContext.xml파일을 사용하거나 별도의 XML파일에서 Spring Batch 설정을 할 수도 있습니다.

아래 예와 같이 Spring 에서는 Spring Batch 설정을 지원하기 위해서 전용 XML 네임스페이스를 제공하는 태그( <batch> )를 기반으로 하고 있습니다. 전용 네임스페이스가 제공하는 태그를 사용하면 Spring Batch 내부의 상세 구현내용을 감추면서 Job, Step, JobRepository 와 같은 핵심 컴포넌트를 쉽게 설정할 수 있고 Batch처리의 동작방식을 정의하거나 커스터마이징이 가능합니다.

  1. applicationContext.xml 에 추가할 경우
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:batch="http://www.springframework.org/schema/batch"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                            http://www.springframework.org/schema/batch
                            http://www.springframework.org/schema/batch/spring-batch-3.0.xsd">
    
        <bean id="serviceManager" class="com.poscoict.glueframework.biz.control.GlueServiceManagerImpl">
            <property name="serviceLoader" ref="serviceLoader" />
            <property name="cacheManager" ref="cacheManager" />
        </bean>
        <bean id="cacheManager" . . . />
        <bean id="serviceLoader" . . . />
    
        <bean id="jobLauncher" . . ./>
    
        <batch:job-repository />
        <bean id="dataSource" . . ./>
        <bean id="transactionManager" . . ./>
    
        <batch:job id="job">
            <batch:step id="step">
                <batch:tasklet>
                    <batch:chunk reader="reader" processor="bizProcessor" writer="writer" commit-interval="1000" />
                </batch:tasklet>
            </batch:step>
        </batch:job>
        <bean id="bizProcessor" . . . />
        <bean id="reader" . . . />
        <bean id="writer" . . . />
    </beans>
    
  2. applicationContext.xml 외에 별도의 xml 파일( ex. biz_batch.xml ) 에서 batch 설정하는 경우
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        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-3.2.xsd">
    
        <import resource="biz_batch.xml"/>
    
        <bean id="serviceManager" class="com.poscoict.glueframework.biz.control.GlueServiceManagerImpl" lazy-init="true">
            <property name="serviceLoader" ref="serviceLoader" />
            <property name="cacheManager" ref="cacheManager" />
        </bean>
        <bean id="cacheManager" . . . />
        <bean id="serviceLoader" . . . />
    </beans>
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:batch="http://www.springframework.org/schema/batch"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
                            http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
                            http://www.springframework.org/schema/batch
                            http://www.springframework.org/schema/batch/spring-batch-3.0.xsd">
    
        <bean id="jobLauncher" . . ./>
    
        <batch:job-repository />
        <bean id="dataSource" . . ./>
        <bean id="transactionManager" . . ./>
    
        <batch:job id="job">
            <batch:step id="step">
                <batch:tasklet>
                    <batch:chunk reader="reader" processor="bizProcessor" writer="writer" commit-interval="1000" />
                </batch:tasklet>
            </batch:step>
        </batch:job>
        <bean id="bizProcessor" . . . />
        <bean id="reader" . . . />
        <bean id="writer" . . . />
    </beans>
    

Glue ItemReader & ItemWriter

Spring Batch에서 제공하는 ItemReader, ItemWriter 외에도 Glue 에서도 ItemReader와 ItemWriter가 있습니다.
Glue Framework에 특화된 GlueCursorItemReader, GlueJdbcBatchItemWriter 도 있으며, applicationContext 설정을 최소화한 GlueDefaultItemReader, GlueDefaultItemWriter 도 있습니다.

GlueCursorItemReader & GlueJdbcBatchItemWriter

Glue 에서는 Item이 DB 일 경우 읽기 쓰기가 가능한 GlueCursorItemReader 와 GlueJdbcBatchItemWriter 를 제공합니다.

  • GlueCursorItemReader

    Batch에서는 대용량 데이터를 다루어야 하는 경우가 많은데 이럴 경우 일반적인 메커니즘에서는 해당 데이터를 한번에 메모리에 올리기 때문에 문제가 발생할 수 있습니다.
    Spring Batch에서는 이 문제를 해결하기 위해 Cursor기반의 JdbcCursorItemReader 를 제공하고 있습니다.
    Glue에서는 Glue의 쿼리 파일을 사용할 수 있도록 GlueCursorItemReader 를 제공하고 있습니다.
    JdbcCursorItemReader 는 SQL문을 설정파일에 작성하지만 GlueCursorItemReader는 주어진 query id를 통해 SQL문을 제공합니다.
    GlueCursorItemReader 의 상속관계 및 메소드는 Java Doc을 참고합니다 (GlueAPI).

    GlueCursorItemReader 의 필수 속성(property)는 다음과 같습니다.

    • dataSource : 참조할 DataSource Bean
    • queryManager : 참조할 GlueQueryManager Bean
    • queryId : query id
    • rowMapper : 참조할 RowMapper bean
    <beans . . .>
        <bean id="biz-dataSource" . . . />
        <bean id="queryManager" . . . />
        <bean id="reader" class="com.poscoict.glueframework.batch.item.GlueCursorItemReader">
            <property name="dataSource" ref="biz-dataSource" />
            <property name="queryManager" ref="queryManager" />
            <property name="queryId" value="select.emp" />
            <property name="rowMapper" ref="empRowMapper" />
        </bean>
        <bean id="empRowMapper" . . . />
    . . .
    
  • GlueJdbcBatchItemWriter

    Spring Batch 에서는 데이터베이스와 연동해서 Item 쓰기 역할을 하는 JdbcBatchItemWriter를 제공하고 있습니다.
    Glue에서는 Glue의 쿼리 파일을 사용할 수 있도록 GlueJdbcBatchItemWriter를 제공하고 있습니다. JdbcBatchItemWriter 는 SQL문을 설정파일에 작성하지만 GlueJdbcBatchItemWriter는 주어진 query id를 통해 SQL문을 제공합니다.
    GlueJdbcBatchItemWriter 의 상속관계 및 메소드는 Java Doc을 참고합니다 (GlueAPI).

    GlueJdbcBatchItemWriter 의 필수 속성(property)는 다음과 같습니다.

    • dataSource : 참조할 DataSource Bean
    • queryManager : 참조할 GlueQueryManager Bean
    • queryId : query id

    그리고 queryId에 해당하는 SQL문의 특성에 따라 추가 속성(property) 를 설정합니다.

    <beans . . .>
        <bean id="biz-dataSource" . . . />
        <bean id="queryManager" . . . />
        <bean id="writer" class="com.poscoict.glueframework.batch.item.GlueJdbcBatchItemWriter">
            <property name="dataSource" ref="dataSource" />
            <property name="queryManager" ref="queryManager" />
            <property name="queryId" value="insert.emp" />
            <property name="assertUpdates" value="true" />
            <property name="itemSqlParameterSourceProvider">
                <bean class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
            </property>
        </bean>
    . . .
    

GlueDefaultItemReader & GlueDefaultItemWriter

ItemReader, ItemWriter는 그 목적에 따라 설정해야할 것들이 많습니다. / Glue에서는 이러한 설정을 최소화한 GlueDefaultItemReader와 GlueDefaultItemWriter를 제공합니다.
그리고 필요한 정보는 JobParameter를 통해 제공합니다.

String stepId = "step";
JobParametersBuilder builder = new JobParametersBuilder();
builder.addString( stepId + ".reader.resource.type", "jdbcDb" );
builder.addString( stepId + ".reader.sql", "select * from emp" );
JobParameters jobParameters = builder.toJobParameters();

해당 Job의 어떤 Step에서 사용하는 Parameter 정보인지를 구분하기 위해서 Key앞에 Step ID를 붙여서 구분합니다.

  • GlueDefaultItemReader

    GlueDefaultItemReader는 JobParameter에 따라 org.springframework.batch.item.file.FlatFileItemReader 또는 org.springframework.batch.item.database.JdbcCursorItemReader 를 생성합니다.
    GlueDefaultItemReader 의 상속관계 및 메소드는 Java Doc을 참고합니다 (GlueAPI).

    <beans . . .>
        <bean id="biz-dataSource" . . . />
        <bean id="reader" class="com.poscoict.glueframework.batch.item.GlueDefaultItemReader" />
        <bean id="writer" . . . />
        <bean id="bizProcessor" . . . />
        <batch:job id="job">
            <batch:step id="step">
                <batch:tasklet>
                    <batch:chunk reader="reader" processor="bizProcessor" writer="writer" commit-interval="1000" />
                </batch:tasklet>
            </batch:step>
        </batch:job>
    . . .
    

    GlueDefaultItemReader 의 JobParameter는 다음과 같은 것이 있습니다.

    • {step id}.reader.resource.type : GlueDefaultItemReader에서 읽어들이는 item 유형으로 3가지를 지원합니다.
      • delimitedFile
      • fixedLengthFile
      • jdbcDb
    • {step id}.reader.resource.name : resource.type 이 delimitedFile 또는 fixedLengthFile 인 경우 file 명.
      builder.addString( stepId + ".reader.resource.name", "/emp-input.txt" );
      
    • {step id}.reader.field.names : resource.type 이 delimitedFile 또는 fixedLengthFile 인 경우 파일에서 읽어들인 데이터와 맵핑되는 컬럼을 순서대로 정의. 컴마(,)로 구분함.
      builder.addString( stepId + ".reader.field.names", "empno,ename,deptno" );
      
    • {step id}.reader.vo.type : item 을 담을 VO Class.
      {step id}.reader.query.id 가 사용된 경우 QueryDefinition의 resultType을 활용하므로 생략 가능함.
      builder.addString( stepId + ".reader.vo.type", "sample.vo.EmpVO" );
      
      <query id="emp.select" desc="" resultType="sample.vo.EmpVO" isNamed="false">
          <![CDATA[
      select EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, DEPTNO
      from EMP
          ]]>
      </query>
      
    • {step id}.reader.delimiter : resource.type 이 delimitedFile 일 경우 파일에서 읽어들인 데이터의 구분자.
      builder.addString( stepId + ".reader.delimiter", "," );
      
    • {step id}.reader.columns : resource.type 이 fixedLengthFile 일 경우 파일에서 읽어들인 데이터를 파싱하는 길이 값 정의
      builder.addString( stepId + ".reader.columns", "1-10,11-20,21-30" );
      
    • {step id}.reader.sql : resource.type 이 jdbcDb 일 경우 SQL문.
      builder.addString( stepId + ".reader.sql", "select * from emp" );
      
      <beans . . .>
          <bean id="biz-dataSource" . . . />
          <bean id="reader" class="com.poscoict.glueframework.batch.item.GlueDefaultItemReader">
              <property name="dataSource" ref="biz-dataSource" />
          </bean>
      . . .
      
    • {step id}.reader.query.id : resource.type 이 jdbcDb 일 경우 query id.
      builder.addString( stepId + ".reader.query.id", "emp.select" );
      
      <beans . . .>
          <bean id="biz-dataSource" . . . />
          <bean id="queryManager" . . . />
          <bean id="reader" class="com.poscoict.glueframework.batch.item.GlueDefaultItemReader">
              <property name="dataSource" ref="biz-dataSource" />
              <property name="queryManager" ref="queryManager" />
          </bean>
      . . .
      
  • GlueDefaultItemWriter

    GlueDefaultItemWriter는 JobParameter에 따라 org.springframework.batch.item.file.FlatFileItemWriter 또는 org.springframework.batch.item.database.JdbcBatchItemWriter 를 생성합니다.
    GlueDefaultItemWriter 의 상속관계 및 메소드는 Java Doc을 참고합니다 (GlueAPI).

    <beans . . .>
        <bean id="biz-dataSource" . . . />
        <bean id="reader" . . . />
        <bean id="writer" class="com.poscoict.glueframework.batch.item.GlueDefaultItemWriter" />
        <bean id="bizProcessor" . . . />
        <batch:job id="job">
            <batch:step id="step">
                <batch:tasklet>
                    <batch:chunk reader="reader" processor="bizProcessor" writer="writer" commit-interval="1000" />
                </batch:tasklet>
            </batch:step>
        </batch:job>
    . . .
    

    GlueDefaultItemWriter 의 JobParameter는 다음과 같은 것이 있습니다.

    • {step id}.writer.resource.type : GlueDefaultItemWriter에서 쓰기 가능한 item 유형으로 3가지를 지원합니다.
      • delimitedFile
      • formatFile
      • jdbcDb
    • {step id}.writer.resource.name : resource.type 이 delimitedFile 또는 formatFile 인 경우 file 명.
      builder.addString( stepId + ".writer.resource.name", "/output/emp.out" );
      
    • {step id}.writer.field.names : resource.type 이 delimitedFile 또는 formatFile 인 경우 기록하는 데이터와 맵핑되는 컬럼을 순서대로 컴마(,)로 구분해서 정의.
      builder.addString( stepId + ".writer.field.names", "user_id,user_nm,dept_id" );
      
    • {step id}.writer.field.format : resource.type 이 formatFile 인 경우 String Format 정의
      builder.addString( stepId + ".writer.field.format", "%-30s%-30s%-10s" );
      
    • {step id}.writer.delimiter : resource.type 이 delimitedFile 일 경우 구분자.
      builder.addString( stepId + ".writer.field.delimiter", "," );
      
    • {step id}.writer.sql : resource.type 이 jdbcDb 일 경우 SQL문.
      builder.addString( stepId + ".writer.sql", "insert into tb_users(user_id,user_nm,dept_id) values(:user_id,:user_nm,:dept_id)" );
      
      <beans . . .>
          <bean id="biz-dataSource" . . . />
          <bean id="queryManager" . . . />
          <bean id="writer" class="com.poscoict.glueframework.batch.item.GlueDefaultItemWriter">
              <property name="dataSource" ref="biz-dataSource" />
          </bean>
      . . .
      
    • {step id}.writer.query.id : resource.type 이 jdbcDb 일 경우 query id.
      builder.addString( stepId + ".writer.query.id", "users.insert" );
      
      <beans . . .>
          <bean id="biz-dataSource" . . . />
          <bean id="queryManager" . . . />
          <bean id="writer" class="com.poscoict.glueframework.batch.item.GlueDefaultItemWriter">
              <property name="dataSource" ref="biz-dataSource" />
              <property name="queryManager" ref="queryManager" />
          </bean>
      . . .
      

GlueCompositeCursorReader & GlueCompositeFileReader

추후

Glue JobLauncher

Job을 실행시키기 위해서는 JobLauncher가 필요합니다.
이미 언급했듯, Spring Batch는 Scheduler가 아니기 때문에, Quartz 등을 통해 JobLauncher를 이용해서 Job을 실행시키는 구조가 될 것입니다.

다음은 Job를 테스트할 수 있는 소스 일부입니다.

  • TestJob.java : jobLauncher 를 통해 sampleJob 을 실행함.
    import org.springframework.batch.core.Job;
    import org.springframework.batch.core.JobParameters;
    import org.springframework.batch.core.launch.JobLauncher;
    
    import com.poscoict.glueframework.context.GlueStaticContext;
    
    public class TestJob {
        public static void main( String arg[] ) throws Exception {
            JobLauncher jobLauncher
                = GlueStaticContext.getBeanFactory().getBeanObject( "jobLauncher", JobLauncher.class );
            Job job
                = GlueStaticContext.getBeanFactory().getBeanObject( "sampleJob", Job.class );
            JobParameters params = . . .
            jobLauncher.run( job, params );
        }
    }
    
  • applicationContext.xml : jobLaunchersampleJob 을 bean으로 등록함.
    <beans . . .>
        <bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
            <property name="jobRepository" ref="jobRepository"/>
        </bean>
        <batch:job-repository />
        <bean id="dataSource" . . ./>
        <bean id="transactionManager" . . ./>
    
        <batch:job id="sampleJob">
            <batch:step id="step" . . . />
        </batch:job>
        . . .
    

위 예제와 같이 Glue에서는 Quartz에서 Job를 실행할 수 있는 GlueQuartzJobLauncher(JobDetail) 와 GlueService 에서 Job를 실행할 수 있는 GlueJobLaunch(GlueActivity) 가 있습니다.

GlueQuartzJobLauncher

Quartz Job Scheduler 를 사용하는 환경에서 GlueQuartzJobLauncher 는 다음과 같이 사용합니다.

<beans . . .>
    . . .
    <bean id="jobDetail-job" class="org.springframework.scheduling.quartz.JobDetailBean">
        <property name="jobClass" value="com.poscoict.glueframework.batch.quartz.GlueQuartzJobLauncher"/>
        <property name="jobDataAsMap">
            <map>
                <entry key="JobName" value="sampleJob"/>
                <entry key="JobLauncherName" value="jobLauncher"/>
            </map>
        </property>
    </bean>
    . . .

GlueJobLaunch

그외 Glue Service 에서 Activity layer에서 Job을 실행 할 수 있는 GlueJobLaunch 는 다음과 같이 사용합니다.

<service . . .>
    . . . 
    <activity name="JobLauncher" class="com.poscoict.glueframework.batch.activity.GlueJobLaunch">
        <property name="job" value="sampleJob" />
        <property name="launcher" value="jobLauncher" />
        <transition . . . />
    </activity>
    . . .

^L

Prev Home Next