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

조익현님의 프로필 이미지
조익현

작성한 질문수

스프링 핵심 원리 - 기본편

@Autowired 의존성 주입 궁금한

해결된 질문

작성

·

228

0

@Autowired
private final MemberRepository memberRepository;
private final MemberRepository memberRepository;

@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
    this.memberRepository = memberRepository;
}

차이점을 잘 몰라서 그런데...

의존성 주입 할때 아래 코드로 하는 이유가 무엇입니까?

답변 2

4

제 미약한 지식이 조금이나마 도움이 되었으면 좋겠습니다!

 

1. 불변성

//필드 주입 방식
@Autowired 
private final MemberRepository memberRepository;
// final이 있다면 생성자로 초기화를 해줘야 하기 때문에 틀린 java 문법이라 생각합니다.

@Autowired
private MemberRepository memberRepository; // final 키워드 없음
// 질문자님의 의도는 이거 였을 것 같아 이것을 기준으로 설명드리도록 하겠습니다!


먼저 위의 코드는 필드 주입(Field Injection)이며, 의존성 주입 이후에도 해당 필드를 변경할 수 있게 됩니다. 이는 객체가 변경 가능(mutable) 상태가 되어, 런타임 중 객체의 상태가 예기치 않게 변경될 위험이 있습니다.

 

// 생성자 주입 방식
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
    this.memberRepository = memberRepository;
}

 

반면 생성자 주입(Constructor Injection)을 사용하게 될 경우, 모든 의존성이 생성자를 통해 주입되고, 필드는 final로 선언될 수 있습니다. 이는 객체가 생성된 이후에도 상태가 변경되지 않는 불변성(immutable)을 보장하여, 객체의 안정성과 신뢰성을 높일 수 있습니다.


2. 명시적인 의존성

생성자 주입(Constructor Injection)을 사용할 경우 필요한 의존성이 명시적으로 드러납니다. 객체를 생성할 때 필요한 모든 의존성이 생성자 파라미터로 제공되기 때문에, 어떤 의존성이 필요한지 바로 알수 있게 됩니다. 이렇게 될 경우 코드의 가독성이 증가하고, 필수 의존성을 누락시키는 실수를 사전에 방지할 수 있게 됩니다.

하지만 필드 주입(Field Injection)을 사용할 경우, 클래스 내부를 들여다보지 않고는 객체 생성에 필요한 의존성이 무엇이 있는지 즉각적으로 알 수 없다는 문제가 있습니다.



3. 테스트 용이성

생성자 주입을 사용하게 될 경우, 테스트 코드에서 특정 구현체나 목(mock) 객체를 쉽게 주입할 수 있습니다. 부연 설명을 하자면 스프링 컨테이너 없이도 순수 자바 코드로 단위 테스트를 진행할 수 있게 되며, 테스트의 단순성과 속도를 개선할 수 있다는 장점이 있습니다.

필드 주입을 사용하게 될 경우, 리플렉션 같은 추가적인 기술을 사용하지 않는 한, 테스트 환경에서 의존성을 주입하기 어렵습니다.

// 참고:

리플렉션이란, 자바에서 제공하는 API로 런타임 시점에서 클래스의 메타데이터를 조회하거나 수정할 수 있게 해주는 기능을 함. 자세히 궁금하다면 한번 찾아보세요!


4. 순환참조 방지

생성자 주입을 사용할 경우, 순환 참조가 있는 경우 어플리케이션 시작 시점에서 바로 오류를 발생시킵니다. 즉, 순환 참조 문제를 조기에 발견하고 수정할 수 있게 해줍니다.

하지만 필드 주입을 사용하게 될 경우, 순환 참조가 발생하더라도 어플리케이션의 시작 시점에는 오류가 발생하지 않고, 런타임 중에만 문제가 드러나서 디버깅하는고 많은 고생을 하게될 것입니다.ㅎㅎ

 


정리하자면 이렇게 크게 4가지 이유로 많은 개발자들이 의존성 주입을 할 때는 생성자 주입을 권장한다고 합니다. But, 상황에 따라 필드 주입이나 setter 주입이 더 적합한 경우도 있으니 스승님께서 가르쳐 주신 방법들도 충분히 숙지하고 있다면 나중에 큰 도움이 될 것 같습니다.

 

// 저도 스프링을 배우는 학생이기 때문에 틀린 내용이 있다면 과감하게 지적해주세요!!

환영합니다~~

 

0

안녕하세요. 조익현님, 공식 서포터즈 David입니다.

본 강의 섹션7 의존관계 자동 주입 에서 생성자 주입에 대해 자세히 설명하고 있사오니 참고해 주세요:)

감사합니다.

조익현님의 프로필 이미지
조익현

작성한 질문수

질문하기