↩뒤로가기

@Autowired는 타입으로 조회한다

@Autowired
private final DiscountPolicy discountPolicy;

타입으로 조회하기 때문에 마치 다음 코드와 유사하게 동작한다. (실제로는 더 많은 기능 제공)

ac.getBean(DiscountPolicy.class)

스프링 빈 조회 파트에서 확인한 것처럼 타입으로 조회 시 빈이 2개 이상일 수가 있다.

DiscountPolicy타입을 공유하는 하위 객체로는 RateDiscountPolicy, FixDiscountPolicy 둘 다 스프링 빈으로 선언하면?

@Component
public class FixDiscountPolicy implements DiscountPolicy{

    private int discountFixAmount = 1000; //1000원 할인

    @Override
    public int discount(Member member, int price) {
        if(member.getGrade() == Grade.VIP){ //enum은 ==을 쓰는 게 맞다.
            return discountFixAmount;
        } else {
            return 0;
        }
    }
}
@Component
public class RateDiscountPolicy implements DiscountPolicy{

    private int discountPercent = 10; //10% 할인

    @Override
    public int discount(Member member, int price) {
        if(member.getGrade() == Grade.VIP){ //enum은 ==을 쓰는 게 맞다.
            return price * discountPercent / 100;
        } else {
            return 0;
        }
    }
}

이 상태에서 @Autowired 실행 시

@Autowired
private DiscountPolicy discountPolicy

동일한 타입을 가진 빈이 2개가 조회되며  예외가 발생한다.

동일한 타입을 가진 빈이 2개가 조회되며 NoUniqueBeanDefinitionException 예외가 발생한다.

이때 하위 타입으로 지정할 수 도 있지만, 하위 타입으로 지정하는 것은 DIP를 위배하고 유연성이 떨어진다. 그리고 이름만 다르고, 완전히 똑같은 타입의 스프링 빈이 2개 있을 때 해결이 안된다. 스프링 빈을 수동 등록해서 문제를 해결할 수도 있으나, 더 좋은 방법들이 있다.

@Autowired 필드 명, @Qualifier, @Primary

조회 대상 빈이 2개 이상일 때 해결 방법

@Autowired 필드 명 매칭

타입매칭을 시도하고, 이때 여러 빈이 있으면 필드 이름, 파라미터 이름으로 빈 이름을 추가 매칭한다.