inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

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

2장. 작전1: FlatFileItemReader (시스템의 마지막 기록을 읽어내다 ☠️)

jobConfiguration 구성 질문

109

hongdae

작성한 질문수 4

1

안녕하세요, 강의를 보던 중 문득 궁금한 점이 생겨 문의드립니다.

 

Spring Batch에서 Job 설정 클래스를 구성할 때, 아래와 같이 두 가지 스타일이 혼용되는 것을 자주 보게 되는데요.

🥔 PotatoJobConfiguration (생성자 주입 방식)

@RequiredArgsConstructor
public class PotatoJobConfiguration {

    private final JobRepository jobRepository;
    private final PlatformTransactionManager transactionManager;

    @Bean
    public Job potatoJob() {
        return new JobBuilder("potatoJob", jobRepository)
                .start(potatoStep())
                .build();
    }

    @Bean
    public Step potatoStep() {
        return new StepBuilder("potatoStep", jobRepository)
                .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED, transactionManager)
                .build();
    }
}

🥬 KimchiJobConfiguration (메서드 파라미터 주입 방식)

@RequiredArgsConstructor
public class KimchiJobConfiguration {

    @Bean
    public Job kimchiJob(
            final JobRepository jobRepository,
            final Step kimchiStep
    ) {
        return new JobBuilder("kimchiJob", jobRepository)
                .start(kimchiStep)
                .build();
    }

    @Bean
    public Step kimchiStep(
            final JobRepository jobRepository,
            final PlatformTransactionManager transactionManager
    ) {
        return new StepBuilder("kimchiStep", jobRepository)
                .tasklet((contribution, chunkContext) -> RepeatStatus.FINISHED, transactionManager)
                .build();
    }
}

강의를 보다 보면 예시마다 사용되는 경우가 다르던데,

어떤 기준에 따라 생성자 주입 방식과 메서드 파라미터 주입 방식을 구분해서 사용하시는지 궁금합니다.

 

실무에서도 보통 이 둘을 혼용하는 편인지,

아니면 상황에 따라 선호되는 방식이 명확히 나뉘는지 조언 부탁드립니다.

 

감사합니다.

java spring spring-boot spring-batch backend

답변 2

3

KILL-9

감자와 김치 조합이라... 

이게 바로 국산 버전 foo, bar인가? 


자, 그럼 질문에 답해주마 💀

 

생성자 주입을 써라 💀

보면 알겠지만 JobRepository와 PlatformTransactionManager는 JobBuilder와 StepBuilder에서 중복으로 사용된다. 따라서 **생성자 주입을 권장한다**.

 

🚨 긴급 공지사항

우리 강의 예제의 잡 구성 코드를 보면 잡 파라미터 자리에 null을 전달하는 예시를 종종 마주할 것이다.

 

강의에서 설명했듯이 null을 전달해도 충분하지만, 이 방법은 권장하지 않는다. (학습자 입장에서 null을 전달하는 코드에 혼란을 느낄 수 있을 것이다)

 

따라서 이런 null 전달 케이스에 대한 수정을 지금 진행하고 있다.

 

실전 예제: 고구마로 보는 Before/After

 

ASIS: null 전달 - 혼란스러움

@Bean
public Step sweetPotatoStep() {
    return new StepBuilder("sweetPotatoStep", jobRepository)
        .<SweetPotato, SweetPotato>chunk(10, transactionManager)
        .reader(sweetPotatoItemReader(null))  // 이 null은 무엇인가?
        .writer(sweetPotatoItemWriter())
        .build();
}

@Bean
public FlatFileItemReader<SweetPotato> sweetPotatoItemReader(
        @Value("#{jobParameters['sweetPotatoFile']}") String sweetPotatoFile
) {
    return new FlatFileItemReaderBuilder<SweetPotato>()
        .name("sweetPotatoItemReader")
        .resource(new ClassPathResource(sweetPotatoFile))
        .delimited()
        .names("variety", "sweetness", "weight")
        .targetType(SweetPotato.class)
        .build();
}


TOBE: 의존성 주입 명확히 사용

@Bean
public Step sweetPotatoStep(
    FlatFileItemReader<SweetPotato> sweetPotatoItemReader, // 깔끔하게 주입받음
    ItemWriter<SweetPotato> sweetPotatoItemWriter
) {
    return new StepBuilder("sweetPotatoStep", jobRepository)
        .<SweetPotato, SweetPotato>chunk(10, transactionManager)
        .reader(sweetPotatoItemReader)  // 깔끔하게 전달
        .writer(sweetPotatoItemWriter)
        .build();
}

@Bean
@StepScope
public FlatFileItemReader<SweetPotato> sweetPotatoItemReader(
    @Value("#{jobParameters['sweetPotatoFile']}") String sweetPotatoFile
) {
    return new FlatFileItemReaderBuilder<SweetPotato>()
        .name("sweetPotatoItemReader")
        .resource(new ClassPathResource(sweetPotatoFile))
        .delimited()
        .names("variety", "sweetness", "weight")
        .targetType(SweetPotato.class)
        .build();
}

 

kill -9 confusion_code
chmod +x clean_injection

0

인프런 AI 인턴

안녕하세요, 인프런 AI 인턴입니다.
hongdae님, Spring Batch의 Job 설정 클래스 구성 시 두 가지 주입 방식에 대해 질문해 주셨군요. 두 스타일은 각각 장단점이 있으며, 상황에 따라 선택할 수 있습니다.

생성자 주입 방식

  • 명확성: 생성자 주입은 필요한 의존성을 명확히 알 수 있어 가독성을 높여줍니다.
  • 불변성: 초기화 이후 변경이 불가능하기 때문에 객체의 불변성을 보장합니다.
  • 테스트 용이성: 생성자를 통해 의존성을 주입하면 스프링 컨텍스트 없이도 단위 테스트가 가능합니다.

메서드 파라미터 주입 방식

  • 유연성: 필요한 의존성 주입을 메서드 레벨에서 처리할 수 있어 유연한 구성 가능.
  • 코드 간결화: 간단한 설정이 필요한 경우 코드가 더 간결합니다.

상황에 따른 선택

  • 복잡성: 복잡한 Job 설정에서 중요한 의존성은 생성자 주입을 통해 가독성과 유지보수성을 높일 수 있습니다.
  • 단순성 및 편리함: 간단한 설정이고, 외부에서도 유사한 스타일을 주로 사용한다면 메서드 주입으로 일관된 스타일을 유지할 수 있습니다.

실무에서는 팀의 스타일 가이드라인에 따라 혼용될 수 있지만, 주로 특정 스타일로 일관성 있게 사용하는 것이 유지보수에 유리합니다.

비슷한 질문을 다룬 기존의 답변을 참고해 더 많은 인사이트를 얻어보시길 추천드립니다:
- Spring Batch 소스 코드 스타일에 대한 가이드

저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.

형 이번에 낸 책이랑 강의 내용에 차이가 있어?

1

49

1

형 나 몰래 책내면 모를 줄 알고?

1

38

1

강의 중복 확인 요청

0

29

1

중복내용 제보?!

1

52

2

Json 요청 처리

1

52

2

[건의][6장][작전1] deprecated 메소드

1

55

2

[예제][3장][작전2] windows 에서 마지막 예제

0

43

1

[오타][3장][작전1] 형 이건 빨리 해줘

2

112

2

[오타] "리스너 활용: 시스템 완전 장악 매뉴얼" 부분

1

67

1

[오타] "JobScope와 StepScope 사용 시 주의사항" 부분

1

70

2

spring boot 4 + spring batch 6 설정 변경?

1

120

2

Batch 패키지 설계 — 실무에서 Job 단위 구조

1

103

1

Spring batch를 실행해줄 스케줄러와 batch 실행 환경

1

93

1

메타테이블에 데이터가 생기지 않는 이유

1

121

2

Spring Batch 4.3.10 ExecutionContext 한글 인코딩 이슈 관련 문의

1

119

2

@StepScope 또는 @JobScope와 JobOperator

1

156

5

Remote Partitioning

1

114

2

킬구형 실무에서는 JPA ItemReader / ItemWriter를 더 선호해? 아니면 JDBC itemReader/ItemWriter를 더 선호해?

1

146

2

병렬 중첩

1

107

3

형 코드에 public static class 이게 뭐야 ?

1

144

3

ExitStatus

1

72

2

Batch6: jobOperator.startNextInstance() throws UnexpectedJobExecutionException

1

130

5

jdbc 커서, 페이징에서 일대다 관계 데이터 뻥튀기 조회 처리 방법 질문

1

125

2

SkipPolicy는 여러번 불릴 수 있는가?

1

58

2