본문 바로가기

WEB

조회 대상 빈이 2개 이상일 때 해결 방법 - @Autowired 필드 명 변경/@Qualifier/@Primary

@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;
    }
}

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {

    private int discountPercent = 10; //10% 할인
    // 이하 로직
}

@Component
public class FixDiscountPolicy implements DiscountPolicy {

    private int discountFixAmount = 1000;
    // 이하 로직
}

스프링의 @ComponentScan은 @Component 찾아다니며  스프링 빈으로 등록한다.

OrderServiceImpl에 DI를 하기 위해 DiscountPolicy를 보니 조건을 만족하는 빈이 2가지(RateDiscountPolicy, fixDiscountPolicy)다.

 

어떤 것을 주입해야할지 애매한 상황에 놓였기 때문에 스프링은 아래와 같은 컴파일 오류를 발생시킨다.

더보기

expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy

 

이를 해결할 수 있는 방법으로 총 3가지가 제시된다.

  • @Autowired 필드 명 매칭
  • @Quilifier -> @Quilifier끼리 매칭 -> 빈 이름 매칭
  • @Primary 사용

@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;
    }

@Component
public class FixDiscountPolicy implements DiscountPolicy {

    private int discountFixAmount = 1000;
	// 이하 로직
}

@Component
public class RateDiscountPolicy implements DiscountPolicy {

    private int discountPercent = 10; //10% 할인
	// 이하 로직
}

 

 

 

// 적용 전
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy discountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = discountPolicy;
    
// 적용 후
@Autowired
public OrderServiceImpl(MemberRepository memberRepository, DiscountPolicy rateDiscountPolicy) {
    this.memberRepository = memberRepository;
    this.discountPolicy = rateDiscountPolicy;

 

 

 

 


@Qualifier 사용

1. @Qualifier 끼리 매칭한다.

2. 빈 이름 매칭

 

* 단점 : 모든 빈에 @Qualifier를 추가해야 한다.

 

@Component
// @RequiredArgsConstructor 롬복에서 자동 생성자 주입을 해줌
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;
    }
}
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {

    private int discountPercent = 10; //10% 할인
	// 이하 로직
}

@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {

    private int discountFixAmount = 1000;
	// 이하 로직
}

@Primary 사용

 

 

@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;
    }
}
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {

    private int discountPercent = 10; //10% 할인
	// 이하 로직
}

@Component
public class FixDiscountPolicy implements DiscountPolicy {

    private int discountFixAmount = 1000;
	// 이하 로직
}

 

우선순위

 

Qualifier > Primary

'WEB' 카테고리의 다른 글

@PathVariable와 model.addAtribute  (0) 2022.05.02
form 태그의 action 속성  (0) 2022.05.02
@PathVariable 애노테이션 등  (0) 2022.04.20
@Controller @RequestMapping  (0) 2022.04.18
에러 -finished with non-zero exit value 1  (0) 2022.04.18