@Component public class FixDiscountPolicy implements DiscountPolicy{...} @Component public class RateDiscountPolicy implements DiscountPolicy{...} @Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy{...}
@Autowired는 빈을 타입으로 조회를 하기 때문에
🔸DiscountPolicy의 하위타입인 RateDiscountPolicy와 FixDiscountPolicy를 빈으로 등록
🔸의존관계를 자동주입하게 된다면 ➡️ NoUniqueBeanDefinitionException이 발생한다.
➡️ discountPolicy에 주입해야할 빈이 2개가 있기 때문.
🔸 @Autowired 필드명 매칭
@Autowired는 같은 타입의 빈이 중복 될 경우, 필드명, 파라미터 이름으로 빈 이름을 매칭한다.
@Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy){...}
🔸 @Qualifier
구분할 수 있는 추가 구분자를 제공하는 방법
1. 빈 등록 시 @Qualifier를 붙인다.~~~ java @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("mainDiscountPolicy")를 못찾는다면 mainDiscountPolicy라는 이름의 스프링 빈을 추가로 찾는다.
🔸 @Primary
▶︎ 우선 순위를 정하는 방법.
▶︎ 같은 타입의 빈이 여러개가 있으면 @Primary를 가진 빈이 우선권을 가진다.-- @Primary 설정 -- @Component @Primary public class RateDiscountPolicy implements DiscoutnPolicy{ } --- 사용코드 --- @Autowired public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) { this.memberRepository = memberRepository; this.discountPolicy = discountPolicy; }
🔸 스프링은 자동보다는 수동, 넓은 범위보다는 좁은 범위의 선택권이 우선순위가 높다.
➡️ 넓은 범위의 @Primary보다는 세세한 이름까지 지정해주는 @Qualifier가 우선순위가 높다.