조회 대상 빈이 2개 이상일 때 해결 방법이 세가지가 있다.
- @Autowired 필드 명 매칭
- @Qualifier끼리 매칭 => 빈 이름 매칭
- @Primary 사용
@Autowired 필드 명 매칭
@Autowired는 타입 매칭을 먼저 시도하고, 같은 타입의 빈이 여러개가 있으면 필드 이름, 파라미터 이름으로 추가적으로 매칭한다.
@Autowired private DiscountPolicy rateDiscountPolicy
이런식으로 필드명을 정의하면 FixDiscountPolicy와 RateDiscountPolicy 중 RateDiscountPolicy를 매칭한다.
@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를 위반하는 것이 아닌가? 였다.
근데 나랑 똑같이 생각하는 사람이 많았는 지 이미 강의 커뮤니티에 질문이 올라와있었다.
결론
클라이언트 코드를 수정해야할 뿐더러 어노테이션을 붙이기 위해 구현체 클래스를 찾아가서 수정해야하기 때문에 OCP를 지키지 못했지만 컴포넌트 스캔의 한계이며, 직접 스프링 빈을 등록하는 불편함 대신 OCP를 포기한 트레이드 오프로 이해하면 된다는 것 같다.
'springboot' 카테고리의 다른 글
[thymeleaf] form 태그 아래 submit이 여러 개일 때 (0) | 2022.04.19 |
---|---|
[스프링 부트 JPA 활용] 도메인 분석 설계 (0) | 2022.03.11 |
[vue.js-springboot] todoApp (0) | 2022.03.05 |
[스프링 핵심 원리] 스프링으로 전환하기 (0) | 2022.03.04 |
[스프링 입문] 6. AOP (0) | 2022.02.27 |