서론
프로젝트를 진행하며 막바지에 간단하게 스프링 배치를 찍먹할 겸, 적용하기로 했다.
강의와 예제를 참고하면서 코드를 작성하는데, 강의에서 @JobScope 와 @StepScope 라는 어노테이션이 사용되었다.
강의에서 안알려주길래 궁금해서 찾아봤다.
참고
https://heekng.tistory.com/178
https://docs.spring.io/spring-batch/docs/current/reference/html/index-single.html#step-scope
본론
Scope?
스코프란, 빈이 관리되는 범위를 의미한다. 기본적으로 singleton으로 설정되어 있으며, 이에 관한 자세한 내용들은 Spring의 Bean Scope와 관련이 깊으니, 따로 검색하는 것을 추천한다.
스코프의 종류는 다음과 같다.
singleton | 기본 스코프, 컨테이너의 시작과 종료까지 유지되는 가장 긴 범위의 스코프 |
prototype | 빈의 생성과 DI까지만 관여, 가장 짧은 스코프 |
request | 웹 요청이 들어오고 나갈때까지 유지되는 스코프 |
session | 웹 세션이 종료될때까지 유지되는 스코프 |
application | 웹 서블릿 컨텍스트와 동일하게 유지되는 스코프 |
@JobScope과 @StepScope
Spring Batch 뿐만 아니라 배치는 기본적으로 Job과 Step이라는 개념이 있다.
Job은 내가 수행할 배치의 작업 단위,
Step은 Job 안에서 수행되는 작은 작업 단위 라고 이해하면 편하다.
그렇다면 @JobScope와 @StepScope는 무엇이냐
Job 또는 Step 빈의 생성이 구동시점이 아닌 빈의 실행시점에 이루어지게 해주는 어노테이션이다.
@JobScope는 Step 선언문에서만 사용이 가능하고, @StepScope는 Step을 구성하는 ItemReader, ItemProcessor, ItemWriter에서 사용 가능하다.
Job과 Step은 Spring 컨테이너의 일부가 아니다. 따라서 빈의 정의를 명시해주거나, @EnableBatchProcessing 어노테이션을 메인애플리케이션에 달아줘야 한다.
왜 이렇게 하는건데?
이는 late binding, lazy binding 이라고 불리는 로딩 행위이다.
이렇게 하면 다음과 같은 이점이 있다.
- JobParameter를 특정 메서드가 실행하는 시점까지 지연시켜 할당이 가능하다.
이렇게 하면 애플리케이션의 구동 시점이 아니라 비즈니스 로직이 필요할 때 JobParameter를 할당할 수 있기 때문에, 프로그램의 유연성이 증대된다. - 병렬처리에 안전하다.
Step의 구성요소인 ItemReader, ItemProcessor, ItemWriter는 각각의 데이터에 간섭이 되면 안된다.
@StepScope 를 사용하면 각각의 상태가 실행될 때 서로의 상태를 침범하지 않고 처리를 완료할 수 있다.
무조건 써야되나요?
아니다. Spring Batch의 공식문서에 의하면 다음과 같이 안내되어있다.
There are some practical limitations of using job-scoped beans in multi-threaded or partitioned steps. Spring Batch does not control the threads spawned in these use cases, so it is not possible to set them up correctly to use such beans. Hence, we do not recommend using job-scoped beans in multi-threaded or partitioned steps.
다중 스레드 또는 분할된 단계에서 작업 범위 Bean을 사용하는 데에는 몇 가지 실질적인 제한 사항이 있습니다.
Spring Batch는 이러한 사용 사례에서 생성된 스레드를 제어하지 않으므로 이러한 Bean을 사용하도록 올바르게 설정하는 것은 불가능합니다.
따라서 다중 스레드 또는 분할된 단계에서는 작업 범위 Bean을 사용하지 않는 것이 좋습니다.
요약하자면, 멀티쓰레드 환경에선 해당 어노테이션의 사용이 적합하지 않다는 의미이다.
Spring Batch는 기본적으로 단일 쓰레드 환경, 즉 순차적인 작업을 지원하는데, 멀티쓰레드의 경우 A쓰레드에서 생성된 빈의 scope 범위를 B쓰레드에서 컨트롤하는것과 유사한 환경이 되어버리기 때문에 Thread-safe 하지 않다는 것이다.
멀티쓰레드 환경에서 Spring Batch를 사용하는 방법은 이곳 에서 확인이 가능하다.
결론
인강을 들으면서 자꾸 강사님이 @JobScope, @StepScope 를 쓰시던데.. 이런거에 대한 설명은 좀 해주는게 좋지않나..라는 생각이 들면서 마구마구 찾아봤다..
그래도 이게 뭔지는 알았으니까 만족 :D
구독 및 하트는 정보 포스팅 제작에 큰 힘이됩니다♡
'프레임워크 > Spring,Springboot' 카테고리의 다른 글
[Spring/Springboot] 스프링 bean과 등록 방법 (0) | 2022.10.23 |
---|