조회 빈이 2개 이상일 경우 해결방법!
@Autowired 필드명 매칭
빈 조회시 타입으로 매칭이 되지만 동일 타입이 2개이상인 빈에 대해서는 타입 다음 필드(파라미터)명으로 빈을 조회 하게 된다. 따라서 동일 타입에 대해 필드(파라미터)명을 다르게 해주면 빈 충돌이 나지 않게된다!
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) { // ✅ 이렇게 파라미터명을 rate~로 다르게 해주면 충돌나지 않음!
this.memberRepository = memberRepository;
this.discountPolicy = rateDiscountPolicy;
}
@Qualifier → @Qualifier 끼리 매칭 → 빈 이름 매칭
빈이름을 변경하는 것이 아니라 @Quilifier(”빈이름지정”) 이 어노테이션을 사용하여 찾는것이다. 아래 예시로 이해해보자.
이렇게 파라미터에 @Qualifier(”mainDiscountPolicy”) 를 붙이게 되면 그 밑의 RateDiscountPolicy 예제와 같이 @Qualifier 어노테이션이 붙은 것중 괄호안에 mainDiscountPolicy 가 명시되어 있는 빈이 매칭된다.
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired // 얘를 생성할때 ApplicationContext에서 자동으로 memberRepository와 discountPolicy를 의존관계 주입으로 넣어준다.
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
}
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {
private int discountPercent = 10;
@Override
public int discount(Member member, int price) {
if(member.getGrade() == Grade.VIP) {
return price * discountPercent / 100;
} else {
return 0;
}
}
}
그런데 만약 @Qualifier 어노테이션이 붙은 것중 mainDiscountPolicy 라는 것이 없다면⁉
그럴때는 스프링컨테이너에 등록된 mainDiscountPolicy 라는 이름의 스프링빈을 추가로 찾는다. 하지만 @Qualifier 는 @Qualifier로 명시되어있는 것만 찾도록 사용하는것이 명확하고 좋다!
@Primary 사용
우선순위를 나타내는 어노테이션이다. @Autowired 시에 여러개의 빈이 매칭되면 @Primary 가 붙은 빈이 우선권을 가진다! 아래 예시는 두개의 클래스를 같이 보여주는 예시이다. 두개의 클래스에서 @Primary 가 붙은 RateDiscountPolicy 클래스가 빈으로 등록이 된다
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {...}
@Component
public class FixDiscountPolicy implements DiscountPolicy {...}
@Qualifier 와 @Primary중 어떤것을 사용하는게 좋을까??
@Primary 는 기본값처럼 동작하지만, @Qualifier 는 우리가 하나하나 명시해줘야하므로 더 상세하다. 이런경우 스프링은 자동보다는 수동이, 넓은 범위의 선택권 보다는 좁은 범위의 선택권이 우선 순위가 더 높다! 따라서 @Qualifier 가 우선권이 더 높으니 해당 어노테이션을 사용하자!!
참고
인프런 - 김영한의 스프링 기본편
'Spring' 카테고리의 다른 글
Thread Pool 이란 도대체 무엇인가! (0) | 2022.06.17 |
---|---|
빈 생명주기 콜백에 대해 알아보자 (0) | 2022.06.04 |
[Springboot] Execution failed for task ':test' 에러 해결방법 (0) | 2022.06.04 |
의존관계가 아닐때 옵셔널처리 (0) | 2022.06.04 |
의존관계 주입방법 (0) | 2022.06.04 |
댓글