스프링/1. 스프링 핵심 원리

37강. 자동주입 똑같은 빈이 2개 이상일 시

sdafdq 2023. 7. 22. 21:24

일단 보통은 우리가 자동주입 할 때, 역할을 DiscountPolicy 이렇게 해서 받는다.

근데 빈이 조회할 때는 타입으로 조회한다. getBean(type) 이런 식으로

저건 인터페이스고, 우리는 두개의 구현체 (rate, fixed) 만들었었다.

둘다 같은 타입이니 오류

 

 

@Autowired 

@Qualifier

@Primary

 

세 솔루션이 있음.

 

일단, @Autowired는 같은 타입일 시 필드 명, 혹은 생성자의 파라미터 명으로 다시 찾음.

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

 

 

public class OrderServiceImpl implements OrderService{
    private final MemberRepository memberRepository;
    private final DiscountPolicy rateDiscountPolicy;

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

 

 

 

@Qualifier 추가적인 이름을 붙여주는? 단, @Qualifier 할 때는 인자도 @Qualifier 붙여 줘야 함.

 

@Component
//@RequiredArgsConstructor
public class OrderServiceImpl implements OrderService{
    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

    public OrderServiceImpl(MemberRepository memberRepository, @Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy) {
        this.memberRepository = memberRepository;
        this.discountPolicy = discountPolicy;
    }

    @Override
    public Order createOrder(Long memberId, String itemName, int itemPrice) {
        Member member = memberRepository.findById(memberId);
        int discountPrice = discountPolicy.discount(member, itemPrice);

        return new Order(memberId, itemName, itemPrice, discountPrice);
    }
}

 

@Qualifier("mainDiscountPolicy")
@Component
public class RateDiscountPolicy implements DiscountPolicy{
    private int discountPercent = 10;
    @Override
    public int discount(Member member, int price) {
        if(member.getGrade() == Grade.VIP){
            return price * discountPercent / 100;
        }else{
            return 0;
        }

    }
}

 

@Qualifier 자체도 없을 때가 있다, 그러면? mainDiscountPolicy라는 이름의 bean을 찾는다.

그래도 명확하게 @Qualifier@Qualifier 끼리 해주는 게 좋다.

 

 

@Primary

우선순위.

@Primary
@Component
public class RateDiscountPolicy implements DiscountPolicy{
    private int discountPercent = 10;
    @Override
    public int discount(Member member, int price) {
        if(member.getGrade() == Grade.VIP){
            return price * discountPercent / 100;
        }else{
            return 0;
        }

    }
}

이렇게 해두면 저걸 최우선 순위로 한다.

예를 들면, mainDB가 있고 subDB가 있으면 mainDB를 @Primary로 해두고, subDB는 @Qualifier 해두면 된다.

 

그리고 @Primary, @Qualifier 둘 중 우선순위는 @Qualifier이다. 더 자세하게 검사하는 거기 때문에.