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

치즈볼님의 프로필 이미지
치즈볼

작성한 질문수

스프링 핵심 원리 - 기본편

생성자 주입에 관하여 질문드립니다!

해결된 질문

작성

·

294

0

좋은 강의 항상 감사드립니다! ^^
다양한 의존관계 주입 방법 부분의 강의를 듣던 중 궁금한 점이 있어 질문 드립니다. 

 

OrderServiceImpl 객체를 생성하여 스프링 빈으로 등록하는 과정에서 궁금한 점이 있습니다.

우선 OrderServiceImpl을 스프링 빈으로 등록하기 전 OrderServiceImpl 객체를 생성하기 위해 아래와 같이 생성자를 호출하게 되고

-> new OrderServiceImpl(memberRepository, discountPolicy);

이 과정에서 생성자의 파라미터로 들어온 객체의 스프링 빈을 찾아와 OrderServiceImpl을 생성한다고 하셨습니다.

강의의 12:40 부분에서 memberRepository와 discountPolicy가 생성이 되어 있지 않다면 스프링이 생성을 한 후 가져온다고 하셨습니다.

 

저는 위 말씀을 생성자 주입 시 생성자의 파라미터로 들어온 객체가 스프링 빈으로 등록되어 있지 않다면 스프링이 그 객체도 자동으로 스프링 빈으로 등록한다고 이해를 하였습니다.

따라서 new OrderServiceImpl(memberRepository, discountPolicy); 코드 실행 시 만약 memberRepository와 discountPolicy가 스프링 빈으로 등록되어 있지 않아도
1. 먼저 스프링이 memberRepository와 discountPolicy를 스프링 빈으로 등록한 후
2. OrderServiceImpl의 스프링 빈 등록과 의존 관계 주입이 동시에 일어난다고 이해하였습니다.

하지만 생성자 주입 사용 시 생성자의 파라미터로 들어오는 객체가 스프링 빈으로 등록되어 있지 않을 경우 NoSuchBeanDefinitionException 예외와 UnsatisfiedDependencyException 예외가 발생하였고,
제가 이해한 부분이 틀린 건지 헷갈려서 질문을 남기게 되었습니다.

 

Q1. 12:40 부분에서 하신 말씀에서 memberRepository와 discountPolicy가 생성이 되어 있지 않다는 뜻이 '스프링 빈으로 등록되어 있지 않다'는 뜻이 아닌 건가요?

Q2. memberRepository와 discountPolicy가 생성이 되어 있지 않아 스프링이 생성을 한 후 가져온다는 뜻이 '생성자의 파라미터로 들어온 객체를 스프링 빈으로 생성하여 가져온다'는 뜻이 아닌 건가요? 

 

답변 1

0

안녕하세요, 치즈볼 님. 공식 서포터즈 codesweaver 입니다.
.

아시다시프 어플리케이션이 실행되면 스프링은 컴포넌트 스캔 방식을 통해 컴포넌트로 등록 할 대상을 검색합니다. 그리고 컴포넌트 들을 빈으로 등록하고, 이후에 의존성 주입과정을 거치게 되는데, 생성자를 통해 의존성 주입을 하게 될  경우에는 이 순서에 문제가 있습니다. 빈을 생성하기 위해 다른 객체가 먼저 생성되어 있어야 하기 떄문인데요.

.

지금 같은 경우 OrderServiceImpl 을 생성하려고 하니, MemberRepository, DiscoutPolicy가 필요한 상황입니다. 그럼 일단 생성자를 호출하기 전에 '빈'에 둘이 있는지를 다시 검색합니다. 그래서 찾을 경우는 이 둘을 먼저 생성한 뒤 이 참조를 OrderServiceImpl 생성자로 전달하며 호출합니다.

.

즉, 스프링 빈이 아닌것은 스프링에서 강제로 의존성 주입을 할 수 없습니다. 이는 개발자가 직접 주입해야 합니다. 이부분을 이해하셨다면 Q1, Q2가 해결되셨을 거에요.

.
감사합니다.

치즈볼님의 프로필 이미지
치즈볼
질문자

감사합니다!

즉 스프링이 memberRepository와 discountPolicy를 생성한다는 뜻이 이 둘을 스프링 빈으로 등록한다는 것이 아니라 스프링 빈에 memberRepository와 discountPolicy가 존재한다면 객체를 생성한다는 뜻인 거군요!

그리고 생성자 주입 시에는 파라미터로 들어오는 객체는 반드시 스프링 빈으로 등록되어 있어야 한다는 거죠?

안녕하세요 치즈볼님!

네, 원래는 MemberService, MemberRepository, DiscountPolicy를 순차적으로 빈으로 등록(등록하기 위해선 객체를 생성해야 하므로 생성자를 한번씩 호출합니다) 해야 합니다.

그런데 지금 같은 경우는 MemberService 생성자를 호출하려면 MemberRepository와 DiscountPolicy가 반드시 필요합니다. 그럼 우선 MemberService 의 등록을 멈추고, MemberRepository, DiscountPolicy 등록을 마친 뒤 MemberService를 등록하는 식으로 순서 조절이 얼어난다고 보시면 됩니다.

.

현재 MemberService의 생성자는 memberRepository, discountPolicy 두개를 받는 생성자 1개 뿐입니다. 다른 방법으로는 MemberService를 생성할 수 없습니다. 그래서 스프링은 이런 경우에 파라미터로 필요한 두 객체가 혹시 스프링 빈으로 등록되어 있을 수 있다고 추측하고, 오류를 뿜어내는 것이 아니라 우선순위를 뒤로 미루어 둔다고 생각하시면 됩니다.

치즈볼님의 프로필 이미지
치즈볼
질문자

감사합니다!

치즈볼님의 프로필 이미지
치즈볼

작성한 질문수

질문하기