개발자 면접 노트

Spring - 의존성 주입(DI)의 종류

해로몬 2025. 6. 25. 19:54

의존성 주입(Dependency Injection, DI)

스프링 컨테이너에서 객체 Bean을 먼저 생성해두고 생성한 객체를 지정한 객체에 주입하는 방식

 

의존성 주입의 종류로는

  • 생성자 주입
  • 필드주입
  • 세터 주입

3가지 방법이 있다.

 


1.생성자 주입(Constructor Injection)

생성자를 통해 의존 객체를 주입받는 방식

*단일 생성자에 한해 @Autowired를 생략 가능

 

✅ 장점

  • 불변성 보장 → final 사용 가능
  • 필수 의존성 보장 → 의존 객체 없으면 객체 생성 자체가 안 됨
  • 순환 의존을 조기에 발견 가능 → 애플리케이션 시작 시점에 오류 발생
  • 테스트 코드 작성 용이 → 생성자 인자로 직접 주입 가능

❌ 단점

  • 의존성이 많아지면 생성자가 길어질 수 있음 → 리팩터링 필요
@Component
public class OrderService {
    private final PaymentService paymentService;

    @Autowired
    public OrderService(PaymentService paymentService) {
        this.paymentService = paymentService;
    }
}

 

 


2.필드 주입(Field Injection)

필드에 직접 @Autowired를 붙여서 주입받는 방식

 

✅ 장점

  • 구현이 가장 간단하고 빠름
  • 테스트용/프로토타입용 코드에 유용

❌ 단점

  • 테스트 어려움 → 필드에 직접 접근 불가 (리플렉션 사용해야 함)
  • 불변성 깨짐 → final 불가
  • Spring이 관리하는 환경에서만 동작 가능
@Component
public class AlertService {

    @Autowired
    private SmsSender smsSender;
}

 


3.세터 주입(Setter Injection)

setter 메서드를 통해 의존객체를 주입받는 방식

생성자 주입과는 다르게 주입받는 객체가 변경될 가능성이 있는 경우에 사용한다.

 

✅ 장점

  • 의존성을 나중에 바꾸거나 설정 가능
  • 필요할 때만 의존성 주입 가능

❌ 단점

  • 객체 생성 시점에 완전한 초기화가 안 될 수도 있음
  • 불변성 보장 안 됨
@Component
public class NotificationService {
    private MessageSender sender;

    @Autowired
    public void setSender(MessageSender sender) {
        this.sender = sender;
    }
}

 

@Autowired로 주입할 대상이 없는 경우에는 오류가 발생한다.

주입할 대상이 없어도 동작하도록 하려면 @Autowired(required = false)를 통해 설정할 수 있다.

 


[정리]

생성자 주입 필드 주입 세터 주입
가독성이 좋고,
테스트코드 작성에 용이하며,
런타임 시점에 유연성이 높다.

*권장하는 방법
가독성이 가장 떨어지기 때문에 유지보수가 어려우며, 의존성 변경이 어려워 유연성이 떨어진다.

*최대한 안쓰는 것이 좋다
생성자 주입에 비해 코드 가독성이 떨어지기 때문에 코드의 양이 많을 때 사용한다.
생성자를 통해 객체를 생성하고, Setter 메서드를 통해 의존성을 주입하는 것이 좋다.