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