[Spring Boot] 의존성 주입시 final vs @Autowired 무엇이 더 좋을까? :: 매운코딩
728x90
300x250

1. DI(의존성 주입)의 구조와 흐름: final vs @Autowired

두 방식의 가장 큰 차이는 **"객체가 언제 만들어지고, 언제 조립되느냐"**의 시점 차이에 있습니다.

① @Autowired (필드 주입)의 흐름

필드 주입은 객체를 먼저 만들고 나서 나중에 부품을 끼워 넣는 방식입니다.

  1. 객체 생성: 스프링이 클래스를 보고 빈(Bean)을 생성합니다. 이때는 기본 생성자를 사용해 일단 '빈 껍데기' 객체를 만듭니다.
  2. 의존성 탐색: 객체 생성이 끝난 후, @Autowired가 붙은 필드를 확인합니다.
  3. 주입: 스프링 컨테이너에서 알맞은 부품(빈)을 찾아 **리플렉션(Reflection)**이라는 기술을 써서 필드에 강제로 꽂아 넣습니다.

비유: 완성된 자동차 차체를 먼저 만들고, 나중에 엔진을 본닛 열고 억지로 집어넣는 것과 같습니다.

② final + 생성자 주입의 흐름 (우리가 쓰는 방식)

생성자 주입은 객체를 만드는 순간에 부품이 없으면 아예 조립을 시작하지 않는 방식입니다.

  1. 의존성 탐색: 스프링이 빈을 생성하기 위해 생성자를 확인합니다. 생성자에 필요한 부품(인자)이 무엇인지 먼저 파악합니다.
  2. 부품 준비: 컨테이너에서 필요한 부품들을 먼저 꺼내옵니다.
  3. 객체 생성 및 주입: 준비된 부품들을 생성자에 넣으면서 객체를 생성합니다. 객체가 태어나는 순간 이미 모든 부품이 장착되어 있습니다.

비유: 레고 성을 만들 때, 기초 블록(부품)이 없으면 성 자체를 쌓기 시작할 수 없는 것과 같습니다.

 

 

 

둘중에 무엇이 더 좋냐고 하면,,, final + 생성자 주입이다.

 

왜?

  1. 불변성 (Immutability): final로 선언하면 객체가 생성될 때 한 번 주입되고 나서 절대로 바꿀 수 없습니다. 실행 중에 의존성이 변하는 사고를 원천 봉쇄합니다.
  2. 누락 방지 (컴파일 타임 체크): 필드 주입(@Autowired)은 객체만 생성하고 의존성 주입을 깜빡해도 컴파일 에러가 안 날 수 있습니다. 하지만 생성자 주입은 의존성이 없으면 아예 객체 생성이 안 되므로 실행 전에 에러를 잡을 수 있습니다.
  3. 테스트 용이성: 스프링 없이 순수 자바 코드로 단위 테스트를 짤 때, 생성자에 Mock(가짜) 객체를 직접 넣어줄 수 있어 매우 편리합니다.
  4. 순환 참조 방지: 두 클래스가 서로를 참조하는 '순환 참조' 문제가 있을 때, 생성자 주입은 앱이 뜨는 시점에 바로 에러를 뱉어주어 문제를 빨리 알 수 있게 해줍니다.

Lombok을 통해 생성자 자동생성 어노테이션 @RequiredArgsConstructor 해주면 굳

728x90

+ Recent posts