배치를 사용하다보면 다양한 scope를 쓰게된다.
예를들어 아래와 같이 step에 JobScope를 붙인다.
@Bean(name = "syncKwJob")
public Job syncJob(Step syncStep) {
return jobBuilderFactory.get("syncKwJob")
.start(syncStep)
.build();
}
@JobScope
@Bean("syncStep")
public Step syncStep(ItemReader<ReplaceKw> trReplaceKwReader, ItemProcessor<ReplaceKw, ReplaceKw> trReplaceKwProcessor, ItemWriter<ReplaceKw> trReplaceKwWriter) {
log.info(">>syncStep");
return stepBuilderFactory.get("syncStep")
.<ReplaceKw, ReplaceKw>chunk(5) // 제네릭 타입을 명확하게 명시
.reader(trReplaceKwReader)
.processor(trReplaceKwProcessor)
.writer(trReplaceKwWriter)
.build();
}
Spring batch scope를 알기 전, 간략하게 Spring scope에 대해서 언급하고 넘어가겠다.
Scope
빈이 존재할 수 있는 범위.
스프링에서 관리하는 객체인 Bean들은 용도에 따라 존재하고 사라지는 시점이 다르다.
1. 싱글톤 스코프 : 일반적인 Bean의 경우 싱글톤 스코프를 가진다. 스프링 컨테이너 시작과 종료까지 유지되며 딱 하나만 생성되어 관리된다.
2. 프로토타입 스코프 : Bean의 생성과 의존관계 주입까지만 관여하고 더는 관리하지 않는다.
3. 웹 관련 스코프 :
(1) request : 웹 요청이 들어오고 나갈 때까지 유지
(2) session : 웹 세션이 생성되고 종료될 때까지 유지
(3) applicaton : 서블릿컨텍스트와 같은 범위로 유지
위에서 본 Scope예제로 확인해 봤을때,
@JobScope : Job이 실행되고 끝날 때 해당 메소드가 생성되고 종료된다.
@StepScope : Step이 실행되고 끝날 때 해당 메소드가 생성되고 종료된다.
이러면 왜 Step메서드에서 @JobScope를 붙이는지 납득이된다.
해당 Scope안에서만 생성/종료 되어야하기 때문이다.
두가지 장점이있다.
1. JobParameter를 실행시점까지 지연시켜 바인딩 할 수 있다.
2. 병렬 처리가 가능해 다른 작업의 개입없이 진행할 수 있다.
job이나 step을 실행할때마다 각각 다른 객체가 생성되는거니까 2번 병렬처리는 이해할 수있다. 그런데 1번 JobParameter를 지연바인딩한다는건 무슨소린가?
JobParameter는 Job이 수행될 때 받는 파라미터이다.
Spring batch는 이 JobParameter가 다르면 다른 job으로 인지하여 job을 수행하고, 같은경우에는 수행하지 않으니 Spring batch에서는 중요하다.
(JobParameter를 Job수행시점의 날짜! 라고 가정하고 생각하면 편하다.)
이렇게 중요한 JobParameter는 때문에 앱 구동시점이 아닌, 해당 로직이 실행되는 시점 에 할당되어야 한다.
이런걸 지연되어 바인딩 된다고 하고, 이런 이점 덕에 어플리케이션의 로직 수행에 관계없이 유연한 설계가 가능하다.
[참고출처]