nodejs 를 공부를 했다가 스프링으로 넘어오니까, 의존관계 주입이라는 새로운 키워드를 접하게 되었습니다. 의존 관계 주입을 쉽게 표현하자면 스프링 컨테이너를 통해서 클래스가 생성 시 필요한 객체를 받아오는 방식 입니다. 이러한 의존 관계 주입 (DI) 는 크게 3가지 방식이 있습니다. (메서드 주입도 있지만 본 포스터에서는 생략하겠습니다.)
1. 생성자 주입
2. 수정자 주입(setter)
3. 필드 주입
본격적인 포스팅을 하기 이전에 인터페이스와 구현체의 관계에 대해서 가정을 해보겠습니다.
그림에서 보다시피 인터페이스는 OrderService, MemberRepository, DiscountPolicy 가 있고 그 아래에는 구현체로 구성되어 있습니다. 참고로 본 포스터에서는 OrderService 를 가지고 설명 드리겠습니다.
결론부터 말한다면 의존 관계 주입은 생성자 주입을 사용하는 것이 좋습니다. 그 이유는 어플리케이션을 키고 끌때까지 의존 관계를 변경하는 경우가 많지 않기 때문입니다. 아래는 생성자 주입 예시 코드입니다.
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
참고로 스프링 컨테이너에 memberRepository, discountPolicy의 스프링 빈이 올라가 있어야지 주입이 가능합니다.
생성자가 1개라면 @Autowired
가 생략이 가능합니다. 위의 코드에서는 생성자가 1개이므로 생략하였습니다.
롬복의 라이브러리를 사용한다면 @RequiredArgsConstructor
를 사용해서 final 이 붙은 필드를 모아서 자동으로 생성자가 사용 가능합니다. 기능이 편리하니 사용해보시는 것을 추천합니다 :)
수정자 주입은 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;
}
}
수정자 주입은 생성자 주입과 달리 의존관계를 재설정이 가능합니다. 간단하게 setter 메서드를 만들어주고 @Autowired
애노테이션을 추가해주면 됩니다.
즉, 의존 관계에서의 변경이 필요하다면 수정자 주입을 활용하시면 되겠습니다.
DI를 할때 기본적으로 필드 주입은 권장드리질 않습니다.
@Component
public class OrderServiceImpl implements OrderService {
@Autowired
private MemberRepository memberRepository;
@Autowired
private DiscountPolicy discountPolicy;
}