SPRING

의존관계 주입 방법

짜비 2021. 5. 17. 17:16

의존관계를 주입하는 방법은 크게 세 가지가 있다.

1. 생성자 주입

2. 수정자 주입

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;
 }
}

생성자에 @Autowired를 붙이는 방식이다.

불변, 필수 의존관계를 나타낼 때 쓰인다. 여기서 불변이란, 의존관계를 클래스 외부에서 수정할 수 없다. (수정자가 노출되어 있지 않기 때문) 또한 필수란, final로 선언해 생성자를 호출할 때 모든 인자가 필수적으로 들어가는 것을 보장함을 의미한다.

 

현재 가장 일반적으로 쓰이는 의존관계 주입 방식이다.

 

 

2. 수정자 주입

@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;
 }
}

수정자(Setter)에 @Autowired를 붙이는 방식이다.

선택, 변경 가능성이 있는 의존관계에 쓰인다. 예를 들어 memberRepository의 의존관계를 수정하고 싶다면, setMemberRepository( ) 에 원하는 구현체를 넣어서 수정할 수 있다.

 

 

3. 필드 주입

@Component
public class OrderServiceImpl implements OrderService {

 @Autowired
 private MemberRepository memberRepository;
 
 @Autowired
 private DiscountPolicy discountPolicy;
}

필드 선언부에 @Autowired를 붙이는 방식이다.

언뜻 보면 코드가 간결해서 편리해 보인다. 하지만 단점이 있어서 사용되지 않는다.

단점 : spring container와 강한 결합이 생긴다. 즉, spring container가 없다면 아무 것도 할 수 없다.

예를 들어, 단위 테스트 코드를 작성할 때, 객체가 field injection으로 되어 있다면 원하는 구현체를 주입할 방법이 없다. 왜냐하면 생성자도, 수정자도 없기 때문이다. 

 

위와 같은 단점 때문에 field injection은 권장되지 않고, 일반적으로는 생성자 주입 방식이 활용된다. 왜 그럴까?

 

생성자 주입 방식의 장점

- 불변 : 대부분의 경우, 의존관계가 한번 주입되면 application이 종료될 때까지 의존관계가 변경되지 않는다. 따라서 의존관계를 변경할 수 있는 수정자를 아예 배제하는 편이 낫다. (단, 의존관계가 변경될 여지가 있을 때는 예외)

 

- 누락 방지 : 객체를 생성할 때, 생성자를 이용하면 주입 데이터가 유입되었을 때 컴파일 에러를 띄운다. 따라서 의존관계가 누락되었을 때 이를 쉽게 발견할 수 있다.

생성자에서 주입 데이터를 누락했을 때 나오는 에러 메시지

- final 사용 가능 : final을 필드에 붙이면 생성자 혹은 선언할 때 값을 initialize 해야 한다. 이런 특성 덕분에 만약 의존관계 주입을 생략했을 때 컴파일러가 의존관계 주입이 이루어지지 않았음을 알려준다.

생성자 코드에서 주입 데이터가 누락되었을 때 자바 컴파일러가 이를 알려준다.

 

 

정리하자면, 생성자 주입을 활용하고 의존관계가 변경될 가능성이 있는 경우에만 수정자 주입을 함께 사용하자.

 

 

 

사진, 내용 출처 : 인프런, 김영한 강사님의 '스프링 핵심 원리 - 기본편' 강좌, 강의자료

https://inf.run/TErf