본문 바로가기
Spring

[Spring] 같은 타입으로 조회된 빈이 여러 개일 경우

by 당코 2022. 12. 28.

@Autowired는 타입으로 빈을 조회한다.

만약 같은 타입으로 등록된 빈이 여러 개가 있을 경우 어떻게 될까?

@Component
public class FixDiscountPolicy implements DiscountPolicy {}
@Component
public class RateDiscountPolicy implements DiscountPolicy {}

DiscountPolicy의 하위 타입인 FixDiscountPolicy와 RateDiscountPolicy 모두 스프링 빈으로 등록을 하였다.

 

@Autowired
private DiscountPolicy discountPolicy

 

이 상황에서 DiscountPolicy에 자동 주입을 실행하면 NoUniqueBeanDefinitionException 오류가 발생한다.

 

이와 같은 문제를 해결하는 방법에 대해 알아보겠다.

 

@Autowired 필드명

@Autowired의 매칭에는 순서가 있다.

먼저 타입 매칭을 시도하고, 그 결과에 여러 빈이 있을 경우 필드명으로 빈 이름을 추가로 매칭한다.

@Autowired
private DiscountPolicy discountPolicy

기존 코드에서 DiscountPolicy과 같은 타입의 빈을 탐색하고, 그 결과가 여러 개일 경우 빈 이름이 discountPolicy인 빈을 찾는다.

@Autowired
private DiscountPolicy rateDiscountPolicy

따라서 이와 같이 필드 이름을 rateDiscountPolicy로 변경하게 되면 타입 매칭을 한 결과인 rateDiscountPolicy, FixDiscountPolicy 중 필드 이름과 같은 rateDiscountPolicy를 자동 주입해 준다.

 

@Qualifier

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

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

빈 등록을 할 때 @Qualifier를 원하는 이름으로 붙여주면 된다.

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

@Qualifier가 붙은 빈 중에서 이름이 동일한 빈을 주입해 준다.

만약 @Qualifier("mainDiscountPolicy")를 찾지 못한다면, mainDiscountPolicy라는 이름의 스프링 빈을 추가로 찾는다.

하지만 @Qualifier는 @Qualifier를 찾는 용도로만 사용하는 것이 좋다.

 

@Primary

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

@Autowired 시에 여러 빈이 매칭되면 @Primary가 우선권을 가진다.

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}

@Component
public class FixDiscountPolicy implements DiscountPolicy {}

RateDiscountPolicy에 @Primary를 붙여 우선권을 가지게 하였다.

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

생성자 주입을 할 때 DiscountPolicy에는 @Primary가 붙은 RateDiscountPolicy가 주입되게 된다.

@Qualifier와 @Primary를 동시에 사용할 경우에는 @Qualifier가 우선순위가 높다.

 

출처 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

'Spring' 카테고리의 다른 글

[Spring] MVC 패턴  (0) 2023.01.04
[Spring] 빈 생명주기 콜백  (0) 2022.12.28
[Spring] 의존관계 자동 주입  (0) 2022.12.27
[Spring] 컴포넌트 스캔  (0) 2022.12.27
[Spring] 싱글톤 패턴과 싱글톤 컨테이너  (2) 2022.12.26