Spring Batch 4.0에서 약 5년의 세월이 흘러 Spring Batch 5.0으로 메이저 버전이 업데이트되었다.
어떤 기능들이 개선되고, 생겼는지 알아보도록 하자.
의존성
Spring Batch5는 Spring framework 6을 의존하기 때문에 최소 Java 17이 필요하다.
그 외에 3rd Party 의존성은 다음과 같다.
- Spring Framework 6
- Spring Integration 6
- Spring Data 3
- Spring AMQP 3
- Spring for Apache Kafka 3
- Micrometer 1.10
다양한 JobParemeter Type
드디어(?) 다양한 JobParemeter type을 제공한다.
4.x 버전까지는 4개의 Type(Long, Double, String, Date)만을 지원했다. 하지만 5.0부터는 JobParameter를 커스텀해서 사용할 수 있다. 아래는 JobParameter의 변경사항인데, Generic이 들어간 걸 확인할 수 있다.
4.x까지는 아래처럼 jobParameter를 적용했다.
parameterName(parameterType)=parameterValue
5부터는 다음과 같이 적용해야 한다.
parameterName=parameterValue,parameterType,identificationFlag
실예로 들면 다음과 같다.
schedule.date=2022-12-12,java.time.LocalDate
위는 기본적으로 적용된 DefaultJobParametersConverter의 결과물이다.
보다 명시적인 방식을 원한다면 JsonJobParametersConverter를 사용할 수 있다.
parameterName='{"value": "parameterValue", "type":"parameterType", "identifying": "booleanValue"}'
이를 위해 BATCH_JOB_EXECUTION_PARAMS DDL이 수정되었다.
숨겨진 자동 설정 명시적으로 변경
StepBuilderFactory, JobBuilderFactory가 Deprecated 되었다. 해당 Factory를 사용하여 Step과 Job을 구성하는 건 일반적으로 사용하는 방식이다.
@Configuration
@EnableBatchProcessing
public class MyJobConfig {
@Autowired
private JobBuilderFactory jobBuilderFactory;
@Bean
public Job myJob(Step step) {
return this.jobBuilderFactory.get("myJob")
.start(step)
.build();
}
}
그러나 이는 사용자가 문서를 읽어 인지하지 않는 한 Builder에서 JobRepository가 생성되고 설정된다는 사실을 숨기고 있다.
그래서 아래와 같이 JobRepository를 명시적으로 제공하는 방식을 사용하길 권장한다.
@Configuration
@EnableBatchProcessing
public class MyJobConfig {
@Bean
public Job myJob(JobRepository jobRepository, Step step) {
return new JobBuilder("myJob", jobRepository)
.start(step)
.build();
}
}
transactionManager 또한 위와 같은 이유로 명시적으로 사용하길 권장하고 있다.
// Sample with v4
@Configuration
@EnableBatchProcessing
public class MyStepConfig {
@Autowired
private StepBuilderFactory stepBuilderFactory;
@Bean
public Step myStep() {
return this.stepBuilderFactory.get("myStep")
.tasklet(..) // or .chunk()
.build();
}
}
// Sample with v5
@Configuration
@EnableBatchProcessing
public class MyStepConfig {
@Bean
public Tasklet myTasklet() {
return new MyTasklet();
}
@Bean
public Step myStep(JobRepository jobRepository, Tasklet myTasklet, PlatformTransactionManager transactionManager) {
return new StepBuilder("myStep", jobRepository)
.tasklet(myTasklet, transactionManager) // or .chunk(chunkSize, transactionManager)
.build();
}
}
Spring Batch 팀에서는 불편함을 감수하더라도 명시적인 코드 작성에 손을 들어줬다. 더보기
DefaultBatchConfiguration 추가
@EnableBatchProcessing가 JobRepository, JobLauncher, StepScope, JobScope 등의 Bean을 등록하고 마법을 부리는 것을 대신할 Configuration class가 추가되었다.
아래처럼 DefaultBatchConfiguration를 상속하여 사용하면 된다.
@Configuration
class MyJobConfiguration extends DefaultBatchConfiguration {
@Bean
public Job job(JobRepository jobRepository) {
return new JobBuilder("myJob", jobRepository)
//define job flow as needed
.build();
}
}
DefaultBatchConfiguration에서는 getDataSource, getTransactionManager, getCharset 등의 다양한 protected method 들을 제공하고 있으며, 자식 클래스에서 이를 Override 하여 간편하게 Batch 설정을 커스터마이즈 할 수 있다.
@Configuration
class MyJobConfiguration extends DefaultBatchConfiguration {
@Bean
public Job job(JobRepository jobRepository) {
return new JobBuilder("job", jobRepository)
// define job flow as needed
.build();
}
@Override
protected Charset getCharset() {
return StandardCharsets.ISO_8859_1;
}
}
⛔️ 주의할 점은 @EnableBatchProcessing과 DefaultBatchConfiguration를 함께 사용하면 안 된다.
@EnableBatchProcessing
@EnableBatchProcessing Annotation이 4.x버전까지 modular만 제공하는 것에 다양한 옵션을 제공한다.
- dataSourceRef
- transactionManagerRef
- executionContextSerializerRef
- charset
- tablePrefix
- maxVarCharLength
- incrementerFactoryRef
- lobHandlerRef
- clobType
- isolationLevelForCreate
- taskExecutorRef
- conversionServiceRef
GraalVM native 지원
GraalVM을 사용하여 Spring Batch 애플리케이션을 기본적으로 컴파일하는 데 필요한 Ahead-Of-Time process 및 Runtime hint를 제공하여 성능이 크게 개선되었다고 한다.
참고
'Spring' 카테고리의 다른 글
10분만에 구현하는 CircuitBreaker (0) | 2023.01.29 |
---|---|
WebFlux에서 micrometer로 모니터링 데이터 수집하기 (0) | 2023.01.11 |
JPA를 이용하여 cursor 기반 페이징 구현 (4) | 2019.12.29 |
Spring WebFlux는 어떻게 적은 리소스로 많은 트래픽을 감당할까? (43) | 2019.06.22 |
Spring Cache 구현 원리 (1) | 2019.03.24 |