Hello Spring Batch!, SpringBatch 시작하기
배치 프로그램이란 ?
대량의 데이터를 일괄 처리하는 배치 작업을 특정 주기에 맞춰서 필요한 작업을 하는 프로그램을 뜻합니다.
Spring에서도 이와 같은 배치 프로그램을 쉽게 적용 할 수 있도록 하는 프레임워크가 Spring Batch 입니다.
Spring Batche는 Accenture와 Spring Source의 합작으로 07년도에 탄생하였습니다.
Accenture의 소스 및 기술, 노하우 등을
Spring Source는 기술 기반과 스프링의 프로그래밍 모델을 도입하였습니다.
즉 거진 Accenture가 소유하고 있던 소스들을 Spring Batch 프로젝트에 기증했다고 할 수 있습니다.
배치의 핵심 패턴
Read: 데이터 베이스, 파일, 큐에서 다량의 데이터를 조회합니다.
Process: 특정 방법으로 데이터를 가공합니다.
Write: 데이터를 수정된 양식으로 다시 저장합니다.
우선 인텔리제이에서 스프링 프레임워크를 개설함과 동시에 Spring Batch 의존성을 추가해줍니다
이후 main 메소드가 있는 SpringBatchApplication에 @EnableBatchProcessing 어노테이션을 붙여줍니다.
@EnableBatchProcessing ?
- 스프링 부트 배치의 자동 설정 클래스가 실행되면서 빈으로 등록된 모든 Job을 검색해서 초기화와 동시에 Job을 수행하도록 구성됩니다.
- 총 4가지 설정 클래스를 실행시키며 스프링 배치의 모든 초기화 및 구성이 이루어지게 됩니다.
- BatchAutoConfiguration
- 스프링 배치가 초기화 될 때 자동으로 실행되는 설정 클래스 입니다.
- Job 을 수행하는 JobLauncherApplicationRunner 빈을 생성하게 됩니다.
- SimpleBatchConfiguration
- JobBuilderFactory 와 StepBuilderFactory 생성합니다
- 스프링 배치의 주요 구성 요소 생성 - 프록시 객체로 생성하게 됩니다.
- BatchConfigurerConfiguration
- BasicBatchConfigurer
- SimpleBatchConfiguration 에서 생성한 프록시 객체의 실제 대상 객체를 생성하는 설정 클래스 입니다.
- 빈으로 의존성 주입 받아서 주요 객체들을 참조해서 사용할 수 있습니다.
- •JpaBatchConfigurer
- JPA 관련 객체를 생성하는 설정 클래스 입니다
- BasicBatchConfigurer
간단한 application.yml을 작성합니다.
기본적은 Spring datasource 설정을 하시고
밑에 batch.jdbc.initialize-schema를 always로 생성합니다.
스프링 배치는 수행관련한 내용들을 메타데이터로 남겨서 테이블에 저장하게 됩니다.
메모리 DB (H2 등)을 사용하지 않는 경우 스키마를 생성하고 메타데이터를 담기게하기 위해 해당 설정을 해줍니다.
시작전에
이번 스프링 배치는 Job -> Step -> Tasklet 형태로 구동됩니다.
Job은 말그대로 하나의 일이라고 생각하시면 됩니다.
Step은 해당 일의 항목 혹은 처리해야할 순서 즉 단계라고 생각하시면됩니다.
최종적으로 TaskLet에서 각 Step에 맞는 실 구현체를 구현합니다.
예를 들어 세탁소를 가야하는 일이 있다고 가정합시다.
세탁소를 가야 하는 일 자체는 Job,
세탁소를 가기위해 옷을 챙기고, 세탁소를 가고, 세탁소에 옷을 맡기는 이 단계를 Step,
실제로 Step 안에서, 옷을 챙긴다, 세탁소를 간다. 옷을 맡긴다는 것을 기술하는 곳이 TaskLet입니다.
Job이 구동 되면 Job 안에 있는 Step을 실행하고 Step이 구동되면 그 안에 Tasklet을 실행하도록 하게됩니다.
이제 간단한 Job을 하나 만들어 보겠습니다.
@Configuration
class HelloJobConfiguration(
val jobBuilderFactory: JobBuilderFactory,
val stepBuilderFactory: StepBuilderFactory
) {
@Bean
fun helloJob(): Job {
return jobBuilderFactory
.get("helloJob")
.start(helloStep1())
.next(helloStep2())
.build()
}
@Bean
fun helloStep1() :Step{
return stepBuilderFactory.get("helloStep1")
.tasklet(
Tasklet() {contribution, chunkContext ->
println("========================")
println(" >> Hello Spring Batch 1!s")
println("========================")
RepeatStatus.FINISHED
})
.build()
}
@Bean
fun helloStep2():Step{
return stepBuilderFactory.get("helloStep2")
.tasklet(
Tasklet() {contribution, chunkContext ->
println("========================")
println(" >> Hello Spring Batch 2!")
println("========================")
RepeatStatus.FINISHED
})
.build()
}
}
@Configuration
하나의 배치 Job을 정의하고 빈을 설정합니다.
JobBuilderFactory
Job을 빌더 형태로 생성 할 수 있는 팩토리 디자인의 클래스입니다.
.get() 메소드를 통해 Job의 이름을 정하고 생성합니다.
StepBuilderFactory
Step을 빌더 형태로 생성 할 수 있는 팩토리 디자인의 클래스입니다.
.get() 메소드를 통해 Job의 이름을 정하고 생성합니다.
해당 코드에선 1가지의 Job(helloJob),
2가지의 Step(helloStep1,helloStep2),
각 Step당 한가지의 1개씩의 TaskLet을 생성합니다.
위와 같이 테스크를 진행한 후
각종 배치 메타 데이터가 저장된 것을 확인 할 수 있습니다.
허나 Always 옵션은 실무에선 위험도가 있기 때문에 잘 사용하지 않습니다.
다음 시간엔 Always를 사용하지 않고 배치를 실행할 수 있도록 DB schema script 파일을 연동해보겠습니다.