StepExecutionListener Interface

Spring Batch에서 Step 수행 선/후처리를 수행하기 위한 Interface이다.

1. 구현 Method

StepExecutionListener Interface의 구현 Method는 다음과 같다.

    public abstract void beforeStep(StepExecution stepexecution);

    public abstract ExitStatus afterStep(StepExecution stepexecution);

1.1. beforeStep() Method

Step의 수행 전에 호출이 되는 Method이다.

beforeStep() Method 설명
속성 설명

파라미터

StepExecution stepExecution

Spring Batch Step의 실행 정보

반환값

void

1.2. afterStep() Method

Step의 수행 완료(정상/중지/에러 등..)에 호출이 되는 Method이다.

afterStep() Method 설명

속성 설명

파라미터

StepExecution stepExecution

Spring Batch Step의 실행 정보

반환값

ExitStatus

Step의 종료 상태정보

2. Sample Source

현재 기본 Source Sample에는 기본 구성만 되어 있다.

자세한 Source Sample은 bxm-batch-default-extension 프로젝트의 DefaultStepListener.java 를 참고한다.

package bxm.batch.dft.listener;

public class DefaultStepListener implements StepExecutionListener{

    private long startTime = 0L;

    @Override
    public void beforeStep(StepExecution stepExecution)
    {
        startTime = System.currentTimeMillis();

        BatchLogUtils.startStepLog(stepExecution, true);
    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution)
    {
        BatchLogUtils.endStepLog(stepExecution, startTime, true);

        // 클래스, Bean 명에 대한 설정은 AfterStep에서 처리.. (BeforeStep으로 변경 금지)
        // BeforeStep에서 수행한다면... 비즈니스 로직의 BeforeStep이 수행이 되기전에 먼저 XML로 정의된 파일 처리가 먼저 Bean이 로딩이되어..
        // jobExecutionContext, stepExecutionContext등을 사용 할 수 가 없음.
        BxmStepInfo bxmStepInfo = BatchContextUtils.getStepInfo(stepExecution.getStepName());
        if(bxmStepInfo != null)
        {
            BatchLogUtils.logging("===============================================================");

            // Tasklet
            if(bxmStepInfo.getTaskletName() != null)
            {
                BatchLogUtils.logging("= Tasklet Class Name  : {} ", new Object[]{bxmStepInfo.getTaskletName()});
            }
            if(bxmStepInfo.getTaskletBeanName() != null)
            {
                BatchLogUtils.logging("= Tasklet Bean Name   : {} ", new Object[]{bxmStepInfo.getTaskletBeanName()});
            }

            // ItemReader
            if(bxmStepInfo.getItemReaderName() != null)
            {
                BatchLogUtils.logging("= Reader Class Name    : {} ", new Object[]{bxmStepInfo.getItemReaderName()});
            }
            if(bxmStepInfo.getItemReaderBeanName() != null)
            {
                BatchLogUtils.logging("= Reader Bean Name     : {} ", new Object[]{bxmStepInfo.getItemReaderBeanName()});
            }

            // ItemProcessor
            if(bxmStepInfo.getItemProcessorName() != null)
            {
                BatchLogUtils.logging("= Processor Class Name : {} ", new Object[]{bxmStepInfo.getItemProcessorName()});
            }
            if(bxmStepInfo.getItemProcessorBeanName() != null)
            {
                BatchLogUtils.logging("= Processor Bean Name  : {} ", new Object[]{bxmStepInfo.getItemProcessorBeanName()});
            }

            // ItemWriter
            if(bxmStepInfo.getItemWriterName() != null)
            {
                BatchLogUtils.logging("= Writer Class Name    : {} ", new Object[]{bxmStepInfo.getItemWriterName()});
            }
            if(bxmStepInfo.getItemWriterBeanName() != null)
            {
                BatchLogUtils.logging("= Writer Bean Name     : {} ", new Object[]{bxmStepInfo.getItemWriterBeanName()});
            }

            // Thread Count
            if(bxmStepInfo.isAsyncStep())
            {
                BatchLogUtils.logging("= Async Step           : {} ", new Object[]{bxmStepInfo.isAsyncStep()});
                BatchLogUtils.logging("= Async Step Size      : {} ", new Object[]{bxmStepInfo.getAsyncStepThreadSize()});
            }
            if(bxmStepInfo.isAsyncItem())
            {
                BatchLogUtils.logging("= Async Item           : {} ", new Object[]{bxmStepInfo.isAsyncItem()});
                BatchLogUtils.logging("= Async Item Size      : {} ", new Object[]{bxmStepInfo.getAsyncItemThreadSize()});
            }

            // Partitioner
            if(bxmStepInfo.isPartitioner())
            {
                BatchLogUtils.logging("= Partitioner Class Name : {} ", new Object[]{bxmStepInfo.getPartitionName()});
                BatchLogUtils.logging("= Partitioner Bean Name  : {} ", new Object[]{bxmStepInfo.getPartitionBeanName()});
                BatchLogUtils.logging("= Partitioner Grid Size  : {} ", new Object[]{bxmStepInfo.getGridSize()});
            }

            BatchLogUtils.logging("===============================================================");
        }

        if((BxmBatchStatusUtils.getReadFileName() != null && !BxmBatchStatusUtils.getReadFileName().isEmpty())
                || (BxmBatchStatusUtils.getWriteFileName() != null && !BxmBatchStatusUtils.getWriteFileName().isEmpty()))
        {
            BatchLogUtils.logging("===============================================================");
            for(String fileName : BxmBatchStatusUtils.getReadFileName())
            {
                BatchLogUtils.logging("= Read File Name     : {} ", new Object[]{fileName});
            }

            for(String fileName : BxmBatchStatusUtils.getWriteFileName())
            {
                BatchLogUtils.logging("= Write File Name     : {} ", new Object[]{fileName});
            }
            BatchLogUtils.logging("===============================================================");
        }

        checkException(stepExecution);

        return stepExecution.getExitStatus();
    }
}

3. 적용 방법

StepExecutionListener를 이용하여 모듈을 개발하였다면 해당 모듈을 배치 Instance Configuration 파일(예:bxm-batch.xml)의 batch-context에 적용할 수 있다.

    ...
    <batch-context>
        <step-listener classname="bxm.batch.dft.listener.DefaultStepListener" order="1"/>
    </batch-context>
    ...

Copyright© Bankwareglobal All Rights Reserved.