스프링

조회 빈이 2개 이상일 때 주입받는 방법

salmon16 2023. 7. 22. 17:58

@Autowired는 타입으로 조회한다

타입으로 조회하면 같은 타입의 빈이 2개 이상일 때 문제가 발생한다.

 

예를 들어 DiscountPolicy의 하위 타입인 FixDiscountPolicy, RateDiscountPolicy둘다 스프링 빈으로 등록시키고

@Autowired
private DiscountPolicy discountPolicy

위와 같이 DiscountPolicy타입으로 의존관계를 주입하면 NoUniqueBeanDefinitionException오류가 발생한다.

해결방법으로 하위타입을 이용해서 의존관계를 주입하면 DIP를 위배하고 유연성이 떨어진다.

 

해결방법에는 크게 3가지가 있다.

  • @Autowired 필드 명 매칭
  • @Qualifier사용
  • @Primary사용

@Autowired 필드 명 매칭

@Autowired는 타입 매칭을 시도하고 여러 빈이 있으면 필드 이름, 파라미터 이름으로 빈 이름을 추가 매칭한다.

기본 코드를 필드 명을 빈 이름으로 변경해 보자

@Autowired
private DiscountPolicy rateDiscountPolicy

필드 명을 rateDiscountPolicy로 변경해 주면 rateDiscountPolicy빈이 등록된다.

@Qualifier사용

@Qualifier은 추가 구분자를 붙여주는 방법이다.

@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy{}
@Component
@Qualifier("subDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {}

RateDiscountPolicy에는 main을 FixDiscountPolicy sub라고 붙여준다.

그리고 생성자 자동 주입 시에 주입을 할 Qualifier의 이름을 적어주면 된다.

@Autowired
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy")DiscountPolicy discountPolicy)
{
	this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}

이렇게 생성자 주입을 하면 mainDiscountPolicy인 RateDiscountPolicy가 주입된다.

 

이때 @Qualifier("mainDiscountPolicy")를 찾지 못하면 스프링 빈이름이 mainDiscountPolicy인 빈을 찾는다.

이도 없으면 에러를 발생시킨다

@Primary사용

@primary는 우선순위를 정하는 방법이다.

@primary애노테이션을 붙여주면 우선순위를 가지게 된다.

 

rateDiscountPolicy가 우선권을 가지게 해 보자

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy{}

이렇게 애노테이션을 달아주면 rateDiscountPolicy가 주입된다.

 

@Primary와 @Qualifier의 우선순위는 좀 더 상세하게 동작하는 @Qualifier이 가지게 된다.

 

출처 : 인프런 스프링 핵심 원리 - 기본 편  김영한

'스프링' 카테고리의 다른 글

빈 생명주기 콜백  (0) 2023.07.24
동일 타입 2개 이상의 빈이 모두 필요할 때  (0) 2023.07.22
생성자 주입의 장점, 룸복사용  (0) 2023.07.21
다양한 의존관계 주입 방법  (0) 2023.07.19
스프링 빈 필터  (0) 2023.07.18