[Spring] Autowired로 의존성 주입 할 Bean이 2개 이상일때 처리

노아카프카·2022년 6월 10일
0

Spring

목록 보기
1/5

- 의존성 주입할 Bean이 2개 이상이라는 말이 무엇이냐?

Policy 라는 Interface가 있다고 가정하자.
Policy를 상속 받은 구현체가 2개 이상인데, 이 구현체들이 모두 스프링 컨테이너에 등록되어있다는 말이다.

예를 들면, RatePolicy implements Policy 와 FixedPolicy implements Policy가 모두 Bean 등록이 되어있어서,
아래 코드가 실행되면, 스프링은 두 policy들 사이에서 선택을 하지 못하기 때문에
NoUniqueBeanDefinitionException 오류가 발생한다.

@Autowired
private Policy policy;

- 해결책은?

1. @Primary

  • 해당 빈이 우선적으로 선택된다.
  • 아래 코드에서, RatePolicy가 Bean 스캐닝에서 우선순위를 가지기 때문에, RatePolicy가 선택된다.
@Component
@Primary
public class RatePolicy implements Policy {}

@Component
public class FixedPolicy implements Policy {}

2. @Qualifier

  • @Qualifier 를 가진 빈끼리 매칭한다.
  • 우선 아래와 같이 어노테이션을 등록한다.
@Bean
@Qualifier("mainPolicy")
public Policy policy() {
	return new ...
}
  • 그 뒤, Policy를 주입받는 부분에서, 생성자 혹은 Setter 메서드의 Param앞에 @Qualifier 어노테이션을 붙여준다.
@Autowired
public OrderServiceImpl(MemberRepository memberRepository,
	@Qualifier("mainPolicy") Policy policy) {
	this.memberRepository = memberRepository;
	this.discountPolicy = policy;
}

3. @Autowired 필드명 매칭

  • @Autowired는 우선 타입매칭(Policy)을 시도하고, Bean이 여러개라면, 필드 이름(FixedPolicy), 파라미터 이름(fixedPolicy)로 빈을 추가한다.
  • 즉, 아래와 같이 코드에서 비록 스프링 컨테이너에는 Policy가 여러개라 할 지라도, FixedPolicy Bean을 선택하게 된다.
@Autowired
private Policy fixedPolicy;

활용

  • 여러 개의 Bean을 모두 사용할 필요가 있을 때에는,
    @Primary와 @Qualifier 를 같이 사용해주면 편리하다.
    Default가 될 Bean에 @Primary를 등록해주고,
    선택적으로 사용할 Bean에는 @Quantifier를 등록한 뒤, 사용될 때마다 명시적으로 @Quantifier를 Param에 붙여서 사용해준다.

0개의 댓글