조회 대상 Bean이 2개 이상일때 해결방법
DiscountPolicy의 구현체인 RateDiscountPolicy, FixDiscountPolicy를 둘다 @Component로 Bean등록을 하였다.
실행시
@Test
void basicScan(){
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);
MemberService memberService = ac.getBean(MemberService.class);
Assertions.assertThat(memberService).isInstanceOf(MemberService.class);
}
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderServiceImpl' defined in file [C:\java\inflearn\core\out\production\classes\hello\core\order\OrderServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy
- '빈이 2개 등록되어있다' 라는 에러 발생
@Autowired
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = rateDiscountPolicy;
}
DiscountPolicy rateDiscountPolicy 필드명 매칭시 에러가 발생하지않는다.
@Autowired매칭정리
- 타입매칭
- 타입매칭의 결과가 2개이상일때 필드명, 파라미터 명으로 빈 이름 매칭
@Quilifier
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy{
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy{
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
- @Quilifider는 추가 구분자를 붙여주는 방법이다. 주입시 추가적인 방법을 제공하는것이지 빈이름을 변경하는것은 아니다.
- @Quilifider로 주입할때 @Quilifider("mainDiscountPolicy")를 못찾으면 어떻게 될까?
- 그러면 "mainDiscountPolicy"라는 이름의 스프링 빈을 추가로 찾는다.
- @Quilifider는 @Quilifider를 찾는 용도로만 사용하는개 명확하고 좋다고한다!
@Quilifider정리
- @Quilifider끼리매칭
- 빈 이름 매칭
- "NoSuchBeanDefinitionException" 예외발생
▶모든 구현체에 @Quilifider를 사용해야하여 코드가 지저분해진다.
@Primary사용
@Primary는 우선순위를 정하는 방법이다. @Autowired시에 여러 빈이 매칭되면 @Primary가 우선권을 가진다.
▶팀 프로젝트시 Bean에러가 지속 발생한적이있다. 그 당시에는 프로젝트 개발에만 급급하여 스프링내부 구조 및 의존관계와 같이 내부적인 구조를 몰랐었다. 그당시 에러메세지를 구글링한결과 @Primary라는 어노테이션을 사용하라고하여 에러를 해결한적이있었던 기억이난다....!