SpringBatch5 변경사항 정리 (vs SpringBatch4)

반응형
728x90
반응형

SpringBatch 5.0

이전 SpringBatch 공부할때 SpringBatch 4.0 버전이였다. 최근, SpringBatch 복습을 위해 새로 프로젝트를 셋팅하면서 업데이트된 SpringBatch 5.0을 선택했는데, 생각보다 4.0 버전에 달라진 사항들이 있었다. 잊어버리기 전에 정리해보고자 포스팅한다.

 

SpringBatch 5.0 변경사항에 대한 공식 홈페이지는 아래와 같다.

https://docs.spring.io/spring-batch/docs/current/reference/html/whatsnew.html

 

What’s New in Spring Batch 5.0

Spring Batch 5.0 has the following major themes: Java 17 Requirement Major dependencies upgrade Batch infrastructure configuration updates Batch testing configuration updates Job parameters handling updates Execution context serialization updates SystemCom

docs.spring.io

 

 

 

1) Java, Spring Framework 버전

Spring Framework 6 부터 Java 최소 사양이 17이다. SpringBatch 5.0은 Spring Framework 6 기반이므로 최소 Java 17버전 이상이 필요하다.

  • Spring Framework 6
  • Spring Integration 6
  • Spring Data 3
  • Spring AMQP 3
  • Spring for Apache Kafka 3
  • Micrometer 1.10

 

 

2) JobParameter Type 제공 

기존 SpringBatch4에서는 Long, Double, Sring, Date 타입의 파라미터만 가능했다. 이제 SpringBatch5부터는 다양한 타입을 파라미터로 넘길 수 있게되었다.

 

▶ SpringBatch4 파라미터 적용

parameterName(parameterType)=parameterValue

 

▶ SpringBatch5 파라미터 적용

parameterName=parameterValue,parameterType,identificationFlag
  • parameterName : 파라미터 명
  • parameterValue : 파라미터 값
  • parameterType : 파라미터 타입
  • identificationFlag : 식별자 여부 (JOB_EXECUTION_PARAMS 테이블의 IDENTIFYING 컬럼에 들어가게되고, 배치 재실행 가능 여부의 구분값이 된다.)

또한 아래와 같이 json 형태로 전달 가능하다.

parameterName='{"value": "parameterValue", "type":"parameterType", "identifying": "booleanValue"}'

 

 

3) 메타테이블 변경사항 [BATCH_JOB_EXECUTION_PARAMS]

위 2)번으로 개선되면서 메타테이블 변경사항도 생겼다. SpringBatch 5.0 버전의 BATCH_JOB_EXECUTION_PARAMS 테이블은 아래와 같다.

 

이전 SpringBatch 4.0 버전의 BATCH_JOB_EXECUTION_PARAMS 테이블을 기억해보자.

https://devfunny.tistory.com/477

 

스프링배치가 제공하는 배치 메타데이터 저장 테이블 (BATCH_JOB_INSTANCE, BATCH_JOB_EXECUTION, BATCH_JOB_EXEC

JobRepository 스프링 배치가 제공하는 여러 데이터베이스 테이블을 사용하여 배치 메타데이터를 저장한다. 총 6개의 테이블이 존재하는데, 각 테이블 정보에 대해 알아보자. BATCH_JOB_INSTANCE 테이블

devfunny.tistory.com

필드 설명
JOB_EXECUTION_ID 테이블의 기본 키
TYPE_CODE 파라미터 값의 타입을 나타내는 문자열
KEY_NAME 파라미터의 이름
STRING_VAL 타입이 String 인 경우 파라미터의 값
DATE_VAL 타입이 Date 인 경우 파라미터의 값
LONG_VAL 타입이 Long 인 경우 파라미터의 값
DOUBLE_VAL 타입이 Double 인 경우 파라미터의 값
IDENTIFING 파라미터가 식별되는지 여부를 나타내는 플래그

2)번에서 말한 내용과 같이, SpringBatch4에서는 Long, Double, Sring, Date 타입의 파라미터만 가능했기 때문에 위와 같이 SRING_VAL, DATE_VAL 컬럼들이 각각 존재했고, SpringBatch5부터는 다양한 파라미터 타입이 가능해졌기 때문에 파라미터명, 파라미터 타입 등의 컬럼으로 변경된 것으로 확인된다.

 

 

● 위 2), 3)번의 내용 테스트를 진행한 포스팅은 아래를 참고바란다.

https://devfunny.tistory.com/931

 

[Kotlin + SpringBatch5] SpringBatch5의 다양한 파라미터 지원 - Job 생성해서 테스트 및 메타테이블 확인, i

SpringBatch5의 다양한 파라미터 지원 https://devfunny.tistory.com/930 SpringBatch5 변경사항 정리 (vs SpringBatch4) SpringBatch 5.0 이전 SpringBatch 공부할때 SpringBatch 4.0 버전이였다. 최근, SpringBatch 복습을 위해 새로

devfunny.tistory.com

 

 

4) StepBuilderFactory, JobBuilderFactory Deprecated

기존 SpringBatch4의 코드를 SpringBatch5에 넣는다면, 위와 같은 경고가 발생한다. SpringBatch5로 업데이트 되면서 StepBuilderFactory, JobBuilderFactory가 deprecated 되었다.

 

이유를 알아보자.

StepBuilderFactory.java
package org.springframework.batch.core.configuration.annotation;

import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.util.Assert;

/**
 * Convenient factory for a {@link StepBuilder} which sets the {@link JobRepository}
 * automatically.
 *
 * @author Dave Syer
 * @author Mahmoud Ben Hassine
 * @author Jinho Han
 * @deprecated Deprecated as of v5.0 and scheduled for removal in v5.2 in favor of using
 * the {@link StepBuilder}.
 *
 */
@Deprecated(since = "5.0.0", forRemoval = true)
public class StepBuilderFactory {

	private final JobRepository jobRepository;

	/**
	 * Constructor for the {@link StepBuilderFactory}.
	 * @param jobRepository The {@link JobRepository} to be used by the builder factory.
	 * Must not be {@code null}.
	 */
	public StepBuilderFactory(JobRepository jobRepository) {
		Assert.notNull(jobRepository, "JobRepository must not be null");
		this.jobRepository = jobRepository;
	}

	/**
	 * Creates a step builder and initializes its job repository. Note that, if the
	 * builder is used to create a @Bean definition, the name of the step and the bean
	 * name might be different.
	 * @param name the name of the step
	 * @return a step builder
	 */
	public StepBuilder get(String name) {
		return new StepBuilder(name, this.jobRepository);
	}

}

위 코드를 보면 StepBuilderFactory.java 안에서 JobRepository가 생성되고, StepBuilder 객체를 생성할때 파라미터로 보내고있다.

이렇게 되면 우리가 SpringBatch4에서 Step 생성시 사용하던 코드에서 StepBuilderFactory.java 를 들여다보지 않으면 알수가 없다. 

 

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

그렇기 때문에 SpringBatch5에서는 좀더 명시적으로 코드를 작성하도록 업데이트된 것으로 보인다.

 

SpringBatch5 (+Kotlin)
@Bean
fun JobExecutionTestStep1(jobRepository: JobRepository, platformTransactionManager: PlatformTransactionManager): Step {
    return StepBuilder("JobExecutionTestStep1", jobRepository)
        .tasklet({ contribution, chunkContext ->
            println("JobExecutionTestStep1 was executed")
            RepeatStatus.FINISHED
        }, platformTransactionManager)
        .build()
}

 

 

5) @EnableBatchProcessing 어노테이션 권장하지 않음

SpringBatch4의 @EnableBatchProcessing 어노테이션 (+Java)
@SpringBootApplication
@EnableBatchProcessing
public class BatchApplication {
    public static void main(String[] args) {
        SpringApplication.run(BatchApplication.class, args);
    }

}

 

SpringBatch5 부터는 @EnableBatchProcessing 어노테이션을 권장하지 않는다. SpringBatch4에서는 @EnableBatchProcessing 어노테이션을 사용함으로써 SpringBoot의 SpringBatch 자동 구성을 활성화할수있도록 관련된 Bean을 등록해주었지만, SpringBatch5부터는 위 어노테이션을 사용하지 않아도 Bean 등록을 해준다.

 

SpringBatch5 (+Kotlin)
@SpringBootApplication
class KotlinSpringbatchApplication

fun main(args: Array<String>) {
    runApplication<KotlinSpringbatchApplication>(*args)
}

 

 

6) @EnableBatchProcessing 어노테이션 속성 추가 

위 5)번에서 @EnableBatchProcessing 어노테이션을 권장하지 않지만 사용은 가능하다. 이번 SpringBatch5부터 속성이 추가되었다.

DataSource, TransactionManager를 명시적으로 지정이 가능해졌다.

@Configuration
@EnableBatchProcessing(dataSourceRef = "testDataSource", transactionManagerRef = "testTransactionManager")
public class MyJobConfiguration {
	...
}

 

 

7) DefaultBatchConfiguration.java 상속

SpringBatch5 부터는 DefaultBatchConfiguration.java를 상속하여 커스터마이징 할 수 있다. 해당 클래스에서는 다양한 메서드를 제공해준다. DataSource, TransactionManager 설정을 위해 해당 클래스를 사용한다면, JobLauncherApplicationRunner 등의 빈이 등록되지 않아서 아래 9)번과 같이 수동으로 등록해줘야한다.

 

HelloJobConfiguration.java
@RequiredArgsConstructor
@Configuration
class HelloJobConfiguration : DefaultBatchConfiguration() {
    ...   
}

 

 

8) @EnableBatchProcessing 또는 DefaultBatchConfiguration.java 상속하는 경우 배치 잡을 자동 수행하는것을 막았다.

실제로, 이 문제 때문에 배치 프로젝트 셋팅시에 삽질을 좀 했다. (해결방법은 아래 9)번이다.)

SpringBatch5부터(정확히는 SpringBoot 3부터) @EnableBatchProcessing 또는 DefaultBatchConfiguration.java 상속하는 경우에는 자동 실행하는 것을 막아두었다.

 

BatchAutoConfiguration.java
@AutoConfiguration(after = { HibernateJpaAutoConfiguration.class, TransactionAutoConfiguration.class })
@ConditionalOnClass({ JobLauncher.class, DataSource.class, DatabasePopulator.class })
@ConditionalOnBean({ DataSource.class, PlatformTransactionManager.class })
@ConditionalOnMissingBean(value = DefaultBatchConfiguration.class, annotation = EnableBatchProcessing.class)
@EnableConfigurationProperties(BatchProperties.class)
@Import(DatabaseInitializationDependencyConfigurer.class)
public class BatchAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	@ConditionalOnProperty(prefix = "spring.batch.job", name = "enabled", havingValue = "true", matchIfMissing = true)
	public JobLauncherApplicationRunner jobLauncherApplicationRunner(JobLauncher jobLauncher, JobExplorer jobExplorer,
			JobRepository jobRepository, BatchProperties properties) {
		JobLauncherApplicationRunner runner = new JobLauncherApplicationRunner(jobLauncher, jobExplorer, jobRepository);
		String jobNames = properties.getJob().getName();
		if (StringUtils.hasText(jobNames)) {
			runner.setJobName(jobNames);
		}
		return runner;
	}
    
    ...
    
}

위 코드에서 아래 코드 때문에 8)번이 적용된 것을 확인했다.

@ConditionalOnMissingBean(value = DefaultBatchConfiguration.class, annotation = EnableBatchProcessing.class)

 

 

9) JobLauncherApplicationRunner을 새로 생성하기

프로젝트에 8)번의 상황(@EnableBatchProcessing 또는 DefaultBatchConfiguration.java 상속하는 경우)이 설정되어있다면 9)번으로 해결해야한다.

@Configuration
@EnableConfigurationProperties(BatchProperties::class)
internal class BatchConfig {
    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(prefix = "spring.batch.job", name = ["enabled"], havingValue = "true", matchIfMissing = true)
    fun jobLauncherApplicationRunner(
        jobLauncher: JobLauncher,
        jobExplorer: JobExplorer,
        jobRepository: JobRepository,
        properties: BatchProperties
    ): JobLauncherApplicationRunner {
        val runner = JobLauncherApplicationRunner(jobLauncher, jobExplorer, jobRepository)
        val jobName = properties.job.name!!

        if (jobName.isNotEmpty()) {
            runner.setJobName(jobName)
        }

        return runner
    }
}
@ConditionalOnProperty(prefix = "spring.batch.job", name = ["enabled"], havingValue = "true", matchIfMissing = true)

위 코드 때문에 반드시 application.yml의 batch.job.enabled의 값이 아래의 코드처럼 ture이거나 아예 설정되어있지 않아야한다.

batch:
  job:
    enabled: true

 

반응형

Designed by JB FACTORY