[Spring] 빈 조회 - 타입 중복 해결

이신영·2024년 1월 17일
1

Spring

목록 보기
8/16
post-thumbnail
post-custom-banner

문제 상황

public interface DiscountPolicy {

    int discount(Member member, int price);
}

위와같은 할인정책 인터페이스와

public class RateDiscountPolicy implements DiscountPolicy{
	...
public class FixDiscountPolicy implements DiscountPolicy{
	...

할인정책 인터페이스의 구현체가 있다.

@Component
public class OrderServiceImpl implements OrderService{


    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

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

주문 서비스의 구현체 생성자에 인터페이스 DiscountPolicy를 쓴다면?

스프링 컨텍스트 테스트

public class AutoAppConfigTest {

    @Test
    void basicScan(){
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AutoAppConfig.class);
		...
    }
}

AnnotationConfigApplicationContext는 컴포넌트스캔을 할 때RateDiscountPolicyFixDiscountPolicy 중에 누구를 불러와야하는지 몰라서 UnsatisfiedDependencyException 를 띄운다. 이를 해결하기위해서는 DI할때 처리를 해야겠죠?

이제 처리하는 3가지 방법에 대해 알아보자!


@Autowired를 활용하여 필드명에 빈 이름넣기

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

필드주입을 하는 상황이면 필드명에 이름을 rateDiscountPolicy로 명시해서

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

이렇게 넣어주기만해도 정상작동한다.


@Quilifier 쓰기

어노테이션끼리 매칭

단점은 주입 받을 때 모든 코드에 붙여야함

할인 정책 구현체 클래스

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

주문 구현체 클래스

@Component
public class OrderServiceImpl implements OrderService{

    private final MemberRepository memberRepository;
    private final DiscountPolicy discountPolicy;

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

@Primary 쓰기

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

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

이렇게 @Primary를 한곳에 붙여넣으면 우선순위가 최상위로 잡힘 근데 @Quilifier랑 같이쓰면 얘가 우선이됨. 스프링은 대부분 수동>자동 이라고 알아두면 편함 두개 다 @Primary 붙여보니까 똑같이 UnsatisfiedDependencyException오류가 뜨더라구요 ㅎg 하나만 붙여둬야하는듯?


음.. 아직도 좀 불편한데..? 그리고 둘 이상의 빈중에 하나만 쓰는 경우말고 다 쓰는 방법도 있을텐데 진도를 더 빼다보면 나오겠죠?

profile
후회하지 않는 사람이 되자 🔥
post-custom-banner

0개의 댓글