Dev/Spring

[Spring] 생성자 주입을 선택해야 하는 이유

yo0oni 2023. 9. 14. 01:21

인프런 김영한 선생님 스프링 핵심 원리 강의를 듣고 정리한 내용입니다.

 


 

다양한 의존관계 주입 방법

  • 생성자 주입
  • 수정자 주입(setter 주입)
  • 필드 주입
  • 일반 메서드 주입

 

생성자 주입

@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy
discountPolicy) {
     this.memberRepository = memberRepository;
     this.discountPolicy = discountPolicy;
 }
  • 생성자를 통해 의존관계를 주입하는 방법
  • 생성자이기 때문에 딱 1번만 호출되는 것이 보장된다.
  • 불변, 필수 의존관계에서 사용
  • 생성자가 1개 있을 경우 @Autowired를 생략해도 자동 주입된다. (스프링 빈만 해당)

 

수정자 주입 (setter 주입)

@Autowired
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
    this.discountPolicy = discountPolicy;
}
  • 필드의 값을 변경하는 setter를 통해 의존관계를 주입하는 방법
  • 선택, 변경 가능성이 있는 의존관계에서 사용

 

필드 주입

@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
  • 필드에 바로 주입하는 방법
  • 코드가 간결하지만 외부에서 변경이 불가능하여 테스트하기 힘들다. (클린코드 9장 단위 테스트를 읽으면 테스트가 빠르고 간단해야 하는 이유를 알 수 있다.)
  • DI 프레임워크가 없으면 아무 것도 할 수 없다.
  • 사용하지 말자...

 

일반 메서드 주입

@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy
discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}
  • 일반 메서드를 통해 주입하는 방법
  • 한 번에 여러 필드를 주입받을 수 있다.
  • 잘 사용하지 않는다.

 

 

생성자 주입을 사용해야 하는 이유

1. 불변

  • 의존관계 주입은 한 번 일어나면 애플리케이션 종료 시점까지 변경할 일이 없다. (오히려 변하면 안 됨)
  • 수정자 주입을 사용할 경우 메서드를 public으로 열어놔야 한다. → 불변성이 깨진다.
  • 생성자 주입은 객체를 생성할 때 딱 한 번만 호출되므로 이후에 호출되는 일이 없다. → 불변성을 지킨다.

 

2. 누락

  • 생성자 주입을 사용하면 주입 데이터를 누락했을 때 컴파일 오류가 발생한다.
  • 덕분에 어떤 값을 필수로 주입해야 하는지 알 수 있다.

 

3. final 키워드

  • 생성자 주입을 사용하면 필드에 final 키워드를 사용할 수 있기 때문에 누락된 값이 있다면 컴파일 시점에 막아준다.
  • 수정자 주입을 포함한 나머지 주입 방식은 모두 생성자 이후에 호출되므로, 필드에 final 키워드를 사용할 수 없다.

 

결론은 <생성자 주입을 사용하자>이다. 가끔 옵션이 필요하거나 필수값이 아닌 경우에 수정자 주입 방식을 부여하면 된다. 필드 주입은 사용하지 않는 게 좋다.