📌 의존관계 주입에는 크게 3가지 방법이 있습니다.
✔️ 생성자 주입 방식
생성자 주입 방식은 생성자를 통해서 의존관계를 주입 받는 방식입니다.
생성자 방식의 특징은 생성자 호출 시점에 딱 1번만 호출되는 것이 보장되기 때문에
불변객체를 생성하는데 유리합니다.
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired // 생성자 주입 방식
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy
discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
✔️ 수정자 주입 방식
수정자 주입 방식은 setter라 불리는 필드의 값을 변경하는 수정자 메서드를 통해서 의존관계를 주입하는 방법입니다. 주로 변경 가능이 있는 의존관계를 주입하는데 사용됩니다.
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired // 수정자 주입 방식
public void setMemberRepository(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Autowired // 수정자 주입 방식
public void setDiscountPolicy(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
}
✔️ 필드 주입
필드 주입 방식은 코드가 간결해서 좋아보이지만, 외부에서 변경이 불가능해서 테스트하기 힘들다는 단점이 있습니다. 필드 주입 방식은 이러한 이유 때문에 사용하지 않는 것이 좋습니다.
@Component
public class OrderServiceImpl implements OrderService {
@Autowired // 필드 주입 방식
private MemberRepository memberRepository;
@Autowired // 필드 주입 방식
private DiscountPolicy discountPolicy;
}
✔️ 일반 메서드 주입
일반 메서드 주입 방식은 일반 메서드를 통해서 주입받는 방식입니다.
한번에 여러 필드를 주입받을 수 있는 장점이 있지만 일반적으로 잘 사용하지 않는 방식입니다.
@Component
public class OrderServiceImpl implements OrderService {
private MemberRepository memberRepository;
private DiscountPolicy discountPolicy;
@Autowired
public void init(MemberRepository memberRepository, DiscountPolicy
discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
그렇다면 왜 생성자 주입 방식을 사용해야 할까?
위 4가지 방식중에서는 필드 주입이 가장 편해 보이지만, 최근에는 DI 프레임워크 대부분이 생성자 주입방식을 권장하고 있습니다.