Coding/Spring Batch

[SpringBatch] Incrementer() Custom : 직접 별도 클래스 생성하기

shbada 2022. 2. 8. 11:51
728x90
반응형

기존 구현체 사용

스프링 배치는 동일한 JobParameters 로는 성공한 Job의 재실행이 불가능하다고 했다. 하지만 Job을 여러번 수행시켜야하는 경우도 있으므로 해당 경우에 incrementer()을 사용한다.

 

기존 구현체인 RunIdIncrementer() 을 사용할 경우 run.id 를 key 값으로 value 가 1씩 증가하여 Job이 실행된다. 계속적으로 증가되는 파라미터가 존재하므로 다른 파라미터 값들은 동일하도 JobParameters 가 다르게 인식되어 재실행이 가능해진다.

 

  • IncrementerConfiguration.java
package com.spring.batch.job;

import com.spring.batch.job.incrementer.CustomJobParametersIncrementer;
import lombok.RequiredArgsConstructor;
import org.springframework.batch.core.*;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.scope.context.ChunkContext;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/*
--job.name=incrementerJob
 */
 
@Configuration
@RequiredArgsConstructor
public class IncrementerConfiguration {

    // job 생성
    private final JobBuilderFactory jobBuilderFactory;
    private final StepBuilderFactory stepBuilderFactory;

    @Bean
    public Job incrementerJob() {
        return this.jobBuilderFactory.get("incrementerJob")
                /* step start */
                .start(incrementerStep1())
                .next(incrementerStep2())
                // 기존 구현체
                .incrementer(new RunIdIncrementer())
                .build();
    }

    @Bean
    public Step incrementerStep1() {
        return stepBuilderFactory.get("incrementerStep1")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("incrementerStep1");
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }

    @Bean
    public Step incrementerStep2() {
        return stepBuilderFactory.get("incrementerStep2")
                .tasklet(new Tasklet() {
                    @Override
                    public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
                        System.out.println("incrementerStep2");
                        return RepeatStatus.FINISHED;
                    }
                })
                .build();
    }
}

 

스프링 배치에서 제공해주는 기존 구현체의 코드를 보자.

 

  • RunIdIncrementer.java
package org.springframework.batch.core.launch.support;

import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersIncrementer;
import org.springframework.lang.Nullable;

public class RunIdIncrementer implements JobParametersIncrementer {
    // 증가될 key 명 
    private static String RUN_ID_KEY = "run.id";
    private String key;

    public RunIdIncrementer() {
        this.key = RUN_ID_KEY;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public JobParameters getNext(@Nullable JobParameters parameters) {
        // JobParameters 셋팅 
        JobParameters params = parameters == null ? new JobParameters() : parameters;
        
        // parameters의 증가될 key 로 value 얻기 
        JobParameter runIdParameter = (JobParameter)params.getParameters().get(this.key);
        
        long id = 1L;
        if (runIdParameter != null) {
            try {
                // 기존 값의 + 1
                id = Long.parseLong(runIdParameter.getValue().toString()) + 1L;
            } catch (NumberFormatException var7) {
                throw new IllegalArgumentException("Invalid value for parameter " + this.key, var7);
            }
        }

        // 셋팅된 JobParameters로 return 
        return (new JobParametersBuilder(params)).addLong(this.key, id).toJobParameters();
    }
}

 

 

 

직접 Incrementer 만들기

  • CustomIncrementer.java
package com.spring.batch.job.incrementer;

import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersIncrementer;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * incrementer 구현
 */
public class CustomJobParametersIncrementer implements JobParametersIncrementer {
    static final SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd-hhmmss");

    /**
     * Date 를 incrementer 로 지정해보자.
     * @param jobParameters
     * @return
     */
    @Override
    public JobParameters getNext(JobParameters jobParameters) {
        // 해당 날짜-시간으로 설정
        String id = format.format(new Date());

        return new JobParametersBuilder().addString("run.id", id).toJobParameters();
    }
}

 

  • IncrementerConfiguration.java
...
    @Bean
    public Job incrementerJob() {
        return this.jobBuilderFactory.get("incrementerJob")
                /* step start */
                .start(incrementerStep1())
                .next(incrementerStep2())
                // 기존 구현체
//                .incrementer(new RunIdIncrementer())
                // 커스텀 가능
                // 항상 변하는 값 이 생겼다. JOB 을 성공해도 해당 JOB은 계속 실행이 가능하다.
                // 계속 변하는 값 + 동일한 파라미터 -> JobParameters 가 되므로 다른걸로 인식된다.
                .incrementer(new CustomIncrementer())
                .build();
    }
...

 

 

반응형