
Spring Batch에 대한 내용은 아래 블로그를 참고하였습니다.
이번 포스트에는 Spring Batch 5와 Kotlin 기준으로 예제 코드를 중심으로 작성하였습니다.
먼저 프로젝트는 다음과 같은 버전을 사용하고, Spring initializer를 사용해서 프로젝트를 생성하였다.
프로젝트를 생성하고 나서 build.gradle.kts 파일이 생성된다.
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
id("org.springframework.boot") version "3.1.0"
id("io.spring.dependency-management") version "1.1.0"
kotlin("jvm") version "1.8.21"
kotlin("plugin.spring") version "1.8.21"
kotlin("plugin.jpa") version "1.8.21"
}
group = "com.example"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17
repositories {
mavenCentral()
}
dependencies {
implementation("org.springframework.boot:spring-boot-starter-batch")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("io.github.microutils:kotlin-logging:2.0.11") // 코틀린 로깅 라이브러리
runtimeOnly("com.h2database:h2")
runtimeOnly("org.mariadb.jdbc:mariadb-java-client")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.batch:spring-batch-test")
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
Spring Batch 5 이전 버전에는 다음과 같은 방법으로 JobBuilderFactory, StepBuilderFactory 를 의존주입 받아서 사용하는 방식으로 했으나, Spring Batch 5로 릴리즈 되면서 해당 방법은 Deprecated 되었다.
@Configuration
class JobConfiguration (
val jobBuilderFactory: JobBuilderFactory,
val stepBuilderFactory: StepBuilderFactory,
)
Spring Batch 5 부터는 JobRepository 를 명시적으로 선언해서 Job을 생성해야한다.
@SpringBootApplication
class SpringBatchWithKotlinApplication
fun main(args: Array<String>) {
runApplication<SpringBatchWithKotlinApplication>(*args)
}
보통 Application.class에 배치 기능 활성화 하는 어노테이션인 @EnableBatchProcessing 를 선언하지만 Spring boot 3.x에서는 해당 어노테이션을 사용하지 않는다.
Spring boot 3.0의 릴리즈 노트를 보면 위와 같이 @EnableBatchProcessing 는 더 이상 사용되지 않는다. 라고 작성되어 있다. 기존에는 @EnableBatchProcessing 를 사용하면 배치관련 설정을 자동으로 해주지만, Spring Batch 5에서는 Datasoruce, TransactionManager와 같은 설정들을 명시적으로 하는 방법을 지향하는 것 같다.
private val log = KotlinLogging.logger {}
@Configuration
class JobConfiguration {
@Bean
fun job(jobRepository: JobRepository,
transactionManager: PlatformTransactionManager
): Job {
return JobBuilder("testJob", jobRepository)
.start(step(jobRepository, transactionManager))
.build()
}
@Bean
fun step(
jobRepository: JobRepository,
platformTransactionManager: PlatformTransactionManager,
): Step {
return StepBuilder("collectStep", jobRepository)
.tasklet({_, _ ->
log.info{ "hello, world" }
RepeatStatus.FINISHED
}, platformTransactionManager)
.build()
}
}
위와 같이 hello, world 로그를 출력하는 간단한 Job 만들어봤다. application run을 하면 다음과 같이 로그가 출력되는 것을 확인할 수 있다.
DataSource 관련해서 아무런 설정을 하지 않는 경우 자동으로 인메모리 DB인 H2를 사용하는 것을 확인할 수 있고, Job의 이름과 Job을 실행 시킬 때 사용한 파라미터를 확인할 수 있다.
인메모리 DB인 H2 환경이 아닌 다른 DB에서 진행하기 위해서는 DataSource 셋팅이 필요하다. 설정하기 위한 방법은 아래와 같다.
applcation.ymlspring:
datasource:
driver-class-name: org.mariadb.jdbc.Driver
url: jdbc:mariadb://localhost:3306/spring_batch_demo
username: root
password: 1234
위와 같이 DB 설정을 진행한다.
@Bean 설정@Configuration
class DataSourceConfig {
@Bean
fun dataSource(): DataSource {
return DataSourceBuilder.create()
.driverClassName("org.mariadb.jdbc.Driver")
.url("jdbc:mariadb://localhost:3306/spring_batch_demo")
.username("root")
.password("1234")
.build()
}
}
DefaultBatchConfiguration.class 메서드 재정의 하기 @Configuration
public class MyJobConfiguration extends DefaultBatchConfiguration {
@Bean
public Job job(JobRepository jobRepository) {
return new JobBuilder("myJob", jobRepository)
// define job flow as needed
.build();
}
}
DefaultBatchConfiguration을 상속 받은 뒤 get 메서드를 재정의하여 배치 설정을 커스텀할 수 있는데, 위와 같은 방법은 아직 사용해보진 않았다.
MariaDB 설정을 하고 나서 다시 application run 을 하면 다음과 같은 에러가 발생할 것이다.
어떤 테이블이 존재하지 않는다는 에러가 발생하는데, Spring Batch 를 사용하기 위해서는 메타 데이터 테이블들이 필요하다. H2를 사용하는 경우에는 해당 테이블을 자동으로 생성해주지만, MariaDB나 다른 DB를 사용하는 경우에는 개발자가 직접 테이블을 생성해주어야 한다.
이미 Spring Batch에는 메타 데이터 테이블에 대한 스키마가 이미 존재하므로 아래와 같은 설정을 추가해주면 자동으로 테이블이 생성된다.
spring:
batch:
jdbc:
initialize-schema: ALWAYS # 스키마 자동 생성
설정을 하고 난 뒤, 다시 실행 시키면 다음과 같은 테이블이 생성된다.
BATCH_JOB_INSTANCE테이블에서 Job 인스턴스가 하나 추가된 것을 확인할 수 있다. 
BATCH_JOB_INSTANCE는 잡이 실행될 때마다 추가되는 것이 아닌 Argument에 할당받은 고유한JobParameter값에 따라 새로 생성된다.
따라서 JobParameter를 변경하지 않고 다시 Application run을 하게 되면
실행할 작업이 없다는 메세지가 출력된다. 다시 실행 시키기 위해 application을 실행 시킬 때 Argument를 넘겨서 Job을 실행시키면 새로운 JobInstance가 추가된다.
program argument 옵션으로 지정해주었다.
새로운 JobInstance가 추가되고, 해당 Job이 실행되었다.