본문 바로가기

springboot

[스프링 핵심 원리] @Autowired @Qualifier @Primary

 

조회 대상 빈이 2개 이상일 때 해결 방법이 세가지가 있다. 

  1. @Autowired 필드 명 매칭
  2. @Qualifier끼리 매칭 => 빈 이름 매칭
  3. @Primary 사용

 

@Autowired 필드 명 매칭

@Autowired는 타입 매칭을 먼저 시도하고, 같은 타입의 빈이 여러개가 있으면 필드 이름, 파라미터 이름으로 추가적으로 매칭한다. 

@Autowired private DiscountPolicy rateDiscountPolicy

이런식으로 필드명을 정의하면 FixDiscountPolicyRateDiscountPolicyRateDiscountPolicy를 매칭한다. 

 

 

@Qualifier 사용

빈 이름을 변경하는 대신 추가 구분자를 붙여주는 방법이다. 

@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {}
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {}
@Autowired
public OrderServiceImpl(MemberRepository memberRepository,
			@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
}

생성자 주입시 등록한 이름을 적어주면 매칭한다. 

Configuration으로 직접 스프링 빈을 등록할 때도 사용할 수 있다.

단, 타입으로 찾는 것이 아니기 때문에 오타가 났을 때 컴파일 에러로 찾을 수 없다. 

 

@Primary 사용

component에 @Primary를 달아 우선권을 주는 방법이다. 가장 간편하다. 

대신 자동화 기능이기 때문에 상세한 @Qualifier보다는 우선순위가 낮다. 

 

 


 

의문점

강의를 들으면서 의문점이 생겼는데, @Autowired의 필드명 매칭이나 @Qualifier를 사용하게 되면 클라이언트 코드를 수정하기 때문에 OCP를 위반하는 것이 아닌가? 였다. 

 

근데 나랑 똑같이 생각하는 사람이 많았는 지 이미 강의 커뮤니티에 질문이 올라와있었다. 

https://www.inflearn.com/questions/160058

 


결론

클라이언트 코드를 수정해야할 뿐더러 어노테이션을 붙이기 위해 구현체 클래스를 찾아가서 수정해야하기 때문에 OCP를 지키지 못했지만 컴포넌트 스캔의 한계이며, 직접 스프링 빈을 등록하는 불편함 대신 OCP를 포기한 트레이드 오프로 이해하면 된다는 것 같다.