생성자 주입 방식을 사용하는 이유

지정욱·2024년 9월 8일
0

📌 의존관계 주입에는 크게 3가지 방법이 있습니다.

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

✔️ 생성자 주입 방식
생성자 주입 방식은 생성자를 통해서 의존관계를 주입 받는 방식입니다.
생성자 방식의 특징은 생성자 호출 시점에 딱 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 프레임워크 대부분이 생성자 주입방식을 권장하고 있습니다.

  • 대부분의 의존관계 주입은 한번 일어나면 종료시점까지 의존관계를 변경할 일이 없습니다. (대부분 불변하게 설계하기 때문에)
  • 수정자 주입이나, 일반 메서드 주입 방식은 메서드를 사용해야 하므로 public으로 열어두어야 합니다.
  • 실수로 변경할 수 있기 때문에 변경하면 안되는 메서드를 열어두는 것은 좋은 설계 방법이 아닙니다.
  • 하지만 생성자 주입 방식은 객체를 생성할 때 1번만 호출되기 때문에 불변하게 설계할 수 있습니다.
  • 기본으로 생성자 주입을 하고 필요 할 때 수정자 주입 방식을 옵션으로 부여하는 방식으로 코드를 작성해야 합니다.
profile
T자형 개발자가 되자

0개의 댓글