*인프런 김영한 강사님의 강좌를 참고하여 정리한 내용입니다.*
@Component를 클래스에 붙여 스프링 컨테이너에 해당 클래스를 스프링 빈으로 등록할 수 있었다! 그리고 @Autowired를 사용하여 생성자, 필드, 일반 메서드등에 의존관계를 자동 주입할 수 있었다.
생성자에 @Autowired를 통해 해당 파라미터와 스프링 빈에 등록된 객체들중 맞는 타입을 매칭하여 의존관계 주입을 하였다.
만약 같은 인터페이스를 상속한 다른 두 객체가 스프링 빈에 등록되어 같은 타입으로 매칭된 객체가 2개 이상일 경우에는 NoUniqueBeanDefinitionException 예외가 발생한다!
그렇다면 어떻게 의존관계 주입을 해야할까?
3가지 해결방법이 있다.
@Autowired
// private final DiscountPolicy discountPolicy
→ private final DiscountPolicy rateDiscountPolicy
필드명 discountPolicy를 빈 이름으로 변경하면, 먼저 타입 매칭을 시도한 후 그 결과에 여러 빈이 있을 때 해당 필드명을 통해 매칭하여 정상 주입한다.
정리
- 타입 매칭
- 타입 매칭의 결과가 2개 이상일 때 필드 명, 파라미터 명으로 빈 이름 매칭
@Qualifier는 추가 구분자를 붙여주는 방법이다. 주입시 추가적인 매칭 방법을 제공하는 것으로 빈 이름을 변경하는 것은 아니다.
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {
...
}
@Autowired
public OrderServiceImpl(
@Qualifier("mainDiscountPolicy") MemberRepository memberRepository) {
...
}
정리
- @Qualifier끼리 매칭
- 빈 이름 매칭
- 매칭되지 않는다면 NoSuchBeanDefinitionException 예외 발생
@Qualifier → 같은 @Qualifier 끼리 매칭 → 빈 이름 매칭 → 없을경우 예외 발생
@Primary는 우선순위를 정하는 방법이다. @Autowired 시에 여러 빈이 매칭되면 @Primary가 우선권을 가진다.
@Component
@Primary
public class RateDiscountPolicy implemnes DiscountPolicy {}
빈 등록시에 우선권을 등록하면 @Qualifier 없이도 매칭이 된다.
코드에서 자주 사용하는 메인DB의 커넥션을 휙득하는 스프링 빈이 있고 코드에서 특별한 기능으로 가끔 사용하는 서브DB의 커넥션을 휙득하는 스프링이 있는 경우에, 메인DB의 커넥션을 휙득하는 스프링 빈은 @Primary를 적용하여 우선조회를 하고, 서브DB의 커넥션 빈을 휙득할 때는 @Qualifier를 지정하여 명시적으로 휙득 하는 방식으로 활용 가능하다.
우선순위
기본값 처럼 동작하는 @Primary, 매우 상세하게 동작하는 @Qualifier. 스프링은 자동보다 수동이, 넓은 범위의 선택권 보다는 좁은 범위의 선택권이 우선 순위가 높다.
따라서 우선순위는 @Primary < @Qualifier