조회 빈이 2개 이상일 때 문제점 및 해결

Minseok Kim·2024년 1월 31일

Spring

목록 보기
10/13
@Autowired
private DiscountPolicy discountPolicy

@Autowired는 타입으로 조회하기 때문에 ac.getBean(DiscountPolicy.class)와 유사하게 동작한다.

하지만 DiscountPolicy 의 하위 타입인 FixDiscountPolicy , RateDiscountPolicy 둘다 스프링 빈으로 선언하면 문제가 발생한다.

@Component
public class FixDiscountPolicy implements DiscountPolicy {}

@Component
public class RateDiscountPolicy implements DiscountPolicy {}


해결방법
@Autowired 필드 명 매칭

  • @Autowired 는 타입 매칭을 시도하고, 타입 매칭의 결과가 2개 이상일 때 필드 명, 파라미터 명으로 빈 이름 매칭
@Component
public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    @Autowired
    public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = rateDiscountPolicy;
    }
}

고정금액 할인으로 적용하고 싶으면 DiscountPolicy rateDiscountPolicy에서 rateDiscountPolicy을 fixDiscountPolicy로 변경하면 된다.

@Qualifier 사용
1. @Qualifier끼리 매칭
2. 빈 이름 매칭
3. NoSuchBeanDefinitionException 예외 발생

@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy{
	...
}

@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy 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;
    }
    
	...
    
}

@Qualifier 로 주입할 때 @Qualifier("mainDiscountPolicy") 를 못찾으면 mainDiscountPolicy라는 이름의 스프링 빈을 추가로 찾는다. 하지만 경험상 @Qualifier 는 @Qualifier 를 찾는 용도로만 사용하는게 명확하고 좋다.

@Primary 사용
가장 자주 사용하는 방법
@Primary 는 우선순위를 정하는 방법이다.
@Autowired 시에 여러 빈이 매칭되면 @Primary 가 우선권을 가진다.

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy{
	...
}

@Component
public class FixDiscountPolicy implements DiscountPolicy{
    ...
}

참고
우선순위는 @Qualifier가 @Primary보다 우선권이 높다.

출처
김영한 스프링 핵심 원리 - 기본편

0개의 댓글