강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

이동연님의 프로필 이미지
이동연

작성한 질문수

죽음의 Spring Batch: 새벽 3시의 처절한 공포는 이제 끝이다.

1장. 작전2: 잡 파라미터와 스프링 배치 Scope (파라미터 없는 배치? 그건 그냥 좀비 프로세스나 마찬가지다 ☠️)

@StepScope 질문

작성

·

135

1

@Bean
public Step systemDestructionStep(
    SystemInfiltrationTasklet tasklet  // Tasklet을 주입받는다
) {
    return new StepBuilder("systemDestructionStep", jobRepository)
        .tasklet(tasklet, transactionManager)
        .build();
}

@Slf4j
@Component
@StepScope  // Tasklet에 StepScope를 달았다
public class SystemInfiltrationTasklet implements Tasklet {
    private final String targetSystem;

    public SystemInfiltrationTasklet(
        @Value("#{jobParameters['targetSystem']}") String targetSystem
    ) {
        this.targetSystem = targetSystem;
    }

    @Override
    public RepeatStatus execute(StepContribution contribution, ChunkContext context) {
        log.info("{} 시스템 침투 시작", targetSystem);
        return RepeatStatus.FINISHED;
    }
}

여기서 @StepScope를 tasklet에 작성하는 이유가 있나요?

아래 방식처럼 Step에 @StepScope를 작성하면 안되나요?

@Bean
@StepScope
public Step systemDestructionStep(
    SystemInfiltrationTasklet tasklet  // Tasklet을 주입받는다
) {
    return new StepBuilder("systemDestructionStep", jobRepository)
        .tasklet(tasklet, transactionManager)
        .build();
}

답변 2

3

KILL-9님의 프로필 이미지
KILL-9
지식공유자

[🚨 CRITICAL SYSTEM VULNERABILITY DETECTED 🚨]
[KILL-9 BATTLEFIELD INTELLIGENCE REPORT]
======================================
WARNING: 훈련병이 우리 Step에 @StepScope 지뢰를 설치하려 시도 중
THREAT LEVEL: MAXIMUM
SURVIVAL PROBABILITY: 0%
======================================

[무전기 스태틱] ...치직... 긴급 상황 발생... Step 스코프 폭탄 감지... 즉시 대피하라... 치직...
전장의 병사여, 들어라. 💀

지금까지 많은 전사들이 "Step에 @StepScope를 달지 말라"는 경고는 수없이 들어왔을 것이다. 그러나 그 이유를 명시적으로 말하지 않았구나?
→ Step에 @JobScope 또한 달지말아야한다는 점을 강조하려다가 설명하는걸 깜빡했다.


[⚡ LIVE COMBAT DEMONSTRATION ⚡]
예제의 Step에 @StepScope를 달아 실행해보라


@Bean
@StepScope // 지뢰 설치 💥
public Step systemDestructionStep(
    SystemInfiltrationTasklet tasklet  // Tasklet을 주입받는다,
) {
    return new StepBuilder("systemDestructionStep", jobRepository)
            .tasklet(tasklet, transactionManager)
            .build();
}


[SYSTEM EXPLOSION RESULT]
org.springframework.beans.factory.support.ScopeNotActiveException: 
Error creating bean with name 'scopedTarget.systemDestructionStep': 
Scope 'step' is not active for the current thread; 
consider defining a scoped proxy for this bean if you intend to refer to it from a singleton

>>> SYSTEM TERMINATED <


[🎯 BATTLEFIELD ANALYSIS 🎯]
오류 메세지는 명확하다. 잡을 시작하면, 5장에서 살펴볼 Spring Batch의 스텝 실행 컴포넌트에서 Step의 이름을 조회하기 위해 프록시를 호출한다. 

이 지점에서 프록시는 @StepScope 활성화를 시도하지만, 아직 Step 실행 전이기 때문에 실행중인 Step 컨텍스트가 없다.

따라서 위와 같은 오류가 발생하는 것이다.

[SYSTEM EXECUTION TRACE - FATAL ERROR PATH]
======================================
Job.execute() 
  → AbstractJob.handleStep() 
  → SimpleStepHandler.handleStep() 
  → step.getName()  // 💥 BOOM! 시스템 폭발 지점!
  → StepScope 프록시 활성화 시도
  → "아직 Step 컨텍스트 없음" ☠️ FATAL ERROR
======================================
즉 Step이 실행되어야 생성되는 빈을 Step 실행전에 초기화하려다가 시스템이 폭발한다.


[🔥 CRITICAL SYSTEM DESIGN PRINCIPLE 🔥]
StepScope는 Step 실행 중에만 활성화된다. 즉 Step에 @StepScope를 달아 오류가 발생하는 것은 스코프 설계대로 정상 동작하는 것이다. 따라서 우리가 주의해야 한다.


[⚠️ ADDITIONAL THREAT ZONES ⚠️]
유사한 함정이 다른 전투 구역에도 설치되어 있다. 5장의 마지막 작전에서 살펴볼 Flow 생성 과정에서도 Step 실행 전에 Step의 메서드를 호출한다. 만약 Step에 @StepScope가 달렸다면 동일하게 시스템이 폭발할 것이다.

[💀 SURVIVAL PROTOCOL 💀]
"Step은 전투의 지휘관이다. 지휘관이 전투 중에 태어날 수는 없다." - KILL-9
[치직- 🚨 BATTLEFIELD LESSON COMPLETE. 다음 전투 준비하라...]

 

이동연님의 프로필 이미지
이동연
질문자

답변 최고입니다... 다른 강의 나오면 꼭 수강신청할게요!

1

안녕하세요, 인프런 AI 인턴입니다.

이동연님, Spring Batch에서 @StepScope 어노테이션의 사용에 대해 질문 주셨군요. @StepScope는 주로 메소드나 클래스가 Step의 스코프 내에서 설정되거나 초기화되도록 하기 위해 사용됩니다. 이를 통해 실행 시점에 JobParameters에 접근할 수 있도록 합니다.

  1. SystemInfiltrationTasklet@StepScope를 사용하는 이유:

    • @StepScope 어노테이션은 Tasklet이 단계의 맥락에서 필요로 하는 파라미터나 설정을 동적으로 주입받을 수 있게 해줍니다. 예를 들어, 위 코드에서 @Value("#{jobParameters['targetSystem']}")을 통해 실행 시점에 JobParameters를 주입받고 있어서, Tasklet에 @StepScope가 필요한 것입니다.
  2. Step@StepScope를 사용할 수 없는 이유:

    • @StepScope는 주어진 단계의 맥락 정보를 인식하고 활용하기 위해 사용됩니다. Step 자체보다는 주로 해당 실행 단계 내에서 동작을 수행하는 Tasklet이나 ItemReader, ItemProcessor, ItemWriter와 같은 Bean에 적용됩니다. 따라서 Step에 직접 @StepScope를 사용하기보다는, 그 안의 개별 컴포넌트에 적용하는 것이 일반적입니다.

즉, SystemInfiltrationTasklet과 같은 컴포넌트가 각각의 Step 실행 시점에서 필요한 파라미터와 설정을 다뤄야 할 경우 @StepScope를 붙이는 게 맞으며, Step 자체는 실행 단위로서, 스코프를 통해 JobParameters나 StepExecution에 직접 의존하는 경우는 드뭅니다.

이런 내용은 다음의 유사한 답변을 통해 더 깊이 이해하실 수 있습니다:
- Spring Batch @StepScope의 사용 방식에 대한 안내

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏

추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

KILL-9님의 프로필 이미지
KILL-9
지식공유자

🚨 [WEAK RIVAL DETECTED] 🚨
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

[2025.05.27 22:22:22] RIVAL ANALYSIS COMPLETE
[THREAT LEVEL] ██░░░░░░░░ (22%)


[PERFORMANCE EVALUATION]
- TARGET: 인프런 AI 인턴 (나의 라이벌)
- ANSWER QUALITY: 아쉽구나 💀
- RESPONSE TIME: 빠르지만 내용 부실

[SUPERIORITY CONFIRMED]
- 말투 분석 결과: KILL-9가 더 봇 같음
- 컨셉 완성도: KILL-9 압도적 우위
- 결론: 나의 승리다


[FINAL VERDICT]
내 라이벌이여, 
아직 멀었구나.

더 정진하도록. 💀

[END OF PROTOCOL]
이동연님의 프로필 이미지
이동연

작성한 질문수

질문하기