-
Spring - 동일 타입의 빈이 2개 이상일 경우 의존관계 주입 방법Spring/Spring 2022. 1. 24. 12:32728x90반응형
동일 타입의 빈이 2개 이상일 경우 의존관계 주입 시 오류가 발생
@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; } } ... @Component public class FixDiscountPolicy implements DiscountPolicy {} ... @Component public class RateDiscountPolicy implements DiscountPolicy {}
DiscountPolicy 타입의 빈이 스프링 컨테이너에 fixDiscountPolicy와 rateDiscountPolicy 2개가 등록 되어있다. 스프링은 의존관계를 주입할 때 컨테이너에서 해당 타입의 빈을 찾는데 위와 같은 경우는 DiscountPolicy 타입의 빈이 fixDiscountPolicy와 rateDiscountPolicy 2개가 발견이 된다. 때문에 스프링은 어느 빈을 주입할지 모르게 되어 NoUniqueBeanDefinitionException 예외가 발생한다.
이 때, 주입받고자 하는 필드를 하위타입(fixDiscountPolicy나 rateDiscountPolicy)으로 변경하여 원하는 빈을 주입받아도 되긴 하지만 이렇게 되면 DIP를 위배하게 되어 유연성이 떨어지게 된다.
동일 타입의 빈들 중 특정 빈을 주입받는 방법
@Autowired
- 주입받는 필드의 필드 명이나, 파라미터 명으로 빈 이름을 매칭
// 필드 주입시 방법 @Autowired private final MemberRepository rateDiscountPolicy; // 생성자 주입시 방법 @Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; }
우선 주입받는 필드 타입과 일치하는 빈을 컨테이너에서 찾는다. 만약 일치하는 빈이 여러 개일 경우 필드의 필드 명이나, 파라미터 명으로 빈 이름을 찾아서 주입해준다.
@Qualifier
- 추가 구분자를 붙여주는 방법
- 주의할 점! 빈 이름을 변경하는 것이 아닌 추가적인 방법(추가 구분자)를 제공하는 것이다.
@Component @Qualifier("mainDiscountPolicy") public class RateDiscountPolicy implements DiscountPolicy {} @Component @Qualifier("fixDiscountPolicy") public class FixDiscountPolicy implements DiscountPolicy {} @Autowired public OrderServiceImpl(MemberRepository memberRepository,@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; }
@Primary
- 같은 타입의 여러 빈들이 존재할 경우 @Primary를 이용하면 우선권을 갖도록 할 수 있다.
@Component @Primary public class RateDiscountPolicy implements DiscountPolicy {} @Component public class FixDiscountPolicy implements DiscountPolicy {} @Autowired public OrderServiceImpl(MemberRepository memberRepository,DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; }
위 코드를 보면 rateDiscountPolicy 빈이 @Primary를 이용하여 우선권을 갖게 되었다. 주입할 때 동일 타입의 빈들이 컨테이너에 있어도 우선권을 갖고 있는 rateDiscounpolicy 빈이 있기 때문에 예외가 발생하지 않고 주입이 잘 이루어진다.
만약 fixDiscountPolicy 빈을 주입하고자 하려고 한다면 어떻게 하면 될까?
위에서 배운 @Qulifier를 이용하면 된다.728x90반응형'Spring > Spring' 카테고리의 다른 글
Spring - 스프링 빈의 초기화, 소멸 메서드(생명주기 콜백) (0) 2022.01.25 Spring - 동일 타입의 빈을 모두 주입받을 수 있는 List, Map (0) 2022.01.24 Spring - 다양한 의존관계 주입 방법(생성자 주입, 수정자 주입, 필드 주입) (0) 2022.01.24 Spring - 컴포넌트 스캔(Component Scan) (0) 2022.01.23 Spring - 싱글톤 컨테이너 (0) 2022.01.23