본 포스팅은 김영한 강사님의 인프런 강의 "스프링 핵심 원리 - 기본편"을 정리한 포스팅으로 강의 자료에서 사용한 자료를 사용했음을 밝힙니다.
컴포넌트 스캔을 통해 자동으로 빈을 등록할 때 같은 타입의 빈이 두 개 이상 등록될 때가 있다.
다음과 같은 서비스는 @Autowired 어노테이션을 통해 의존 관계를 자동으로 주입하고 있는데
@Component
public class OrderServiceImpl implements OrderService{
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
.
.
.
}
만약 DiscountPolicy 하위 타입인 fixDiscountPolicy와 rateDiscountPolicy 두 개가 스프링 빈에 등록되어있다면 OrderService를 가져오는 과정에서 다음과 같은 오류가 발생할 것이다.
No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy
이를 해결하는 방안은 다음과 같다.
1. @Autowired 필드명 매칭
@Autowired를 통해 의존 관계를 자동으로 주입할 때
가장 먼저 타입으로 매칭을 시도하고 그 다음 파라미터 이름으로 매칭을 시도한다.
그렇기 때문에 fixDiscountPolicy와 rateDiscountPolicy 둘 다 스프링 빈에 등록되어있는 상황에서 fixDiscountPolicy만 사용하고 싶다면 파라미터 이름을 fixDiscountPolicy로 바꾸면 된다.
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy fixDiscountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = fixDiscountPolicy;
}
.
.
.
}
2.@Qualifer 사용
@Component 어노테이션을 사용하여 빈에 등록할 때 각각 이름을 정해준다.
<FixDiscountPolicy>
@Component
@Qualifier("mainDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy{
.
.
.
}
<RateDiscountPolicy>
@Component
@Qualifier("subDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy{
.
.
.
}
그리고 자동 의존 관계 주입에서 이러한 이름을 사용하면 된다.
@Component
public class OrderServiceImpl implements OrderService {
private final MemberRepository memberRepository;
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
this.memberRepository = memberRepository;
this.discountPolicy = discountPolicy;
}
.
.
.
}
만약 @Qualifer("mainDiscountPolicy")를 못 찾으면 스프링 빈에서 빈 이름이 mainDiscountPolicy인 것을 찾는다.
3. @Primary 사용
@Primary 어노테이션을 사용해서 우선 순위를 지정할 수 있다.
FixDiscountPolicy에 @Primary 어노테이션을 달면 RateDiscountPolicy보다 우선순위를 높일 수 있다.
@Component
@Primary
public class FixDiscountPolicy implements DiscountPolicy {
private int discountFixAmount = 1000;
.
.
.
}
스프링에서의 우선순위
스프링에서는 자동보다는 수동이, 넓은 범위보다는 좁은 범위가 우선순위가 높다.
@Primary보다는 @Qualifer의 우선순위가 높다.
'공부 > Spring' 카테고리의 다른 글
[Spring] 스프링 시큐리티 기본 설정 및 BcryptPasswordEncoder를 사용하여 비밀번호 암호화하기 (0) | 2023.01.29 |
---|---|
[Spring][스프링 핵심 원리] 빈 생명주기 콜백 (0) | 2023.01.24 |
[Spring][스프링 핵심 원리] 의존 관계 주입 방법 및 옵션 처리 (0) | 2023.01.19 |
[Spring][스프링 핵심 원리] 스프링 컨테이너와 스프링 (0) | 2023.01.12 |
[InteliiJ] 인텔리제이 단축키 (0) | 2023.01.10 |
댓글