본문 바로가기

back-end/spring

spring/ @Autowired 사용 시 조회 대상 빈이 2개 이상인 경우 처리하기

 

 

@Autowired는 타입으로 조회하기 때문에 선택되는 빈이 한 개가 아닌 경우 NoUiqueBeanDefinitionException이 발생한다. 이를 다음의 3가지 방법으로 해결할 수 있다.

 

1. @Autowired 사용 시 필드 명으로 매칭되게 하기

@Autowired는 일차적으로 타입으로 매칭을 시도하지만 같은 타입의 빈이 있는 경우 필드 이름 및 파라미터 이름으로 빈을 매칭한다.

 

public class  OrderServiceImpl implements OrderService {

@Autowired
private PointPolicy pointPolicy;

...
}

 

@Component
public class FixPointPolicy implements PointPolicy {...}

@Component
public class RatePointPolicy implements PointPolicy {...}

 

따라서 위와 같이 작성된 코드의 경우 PointPolicy를 구현하는 클래스는 FixPointPolicy와 RatePointPolicy가 존재하고, 둘 다 @Component로 등록되었다. 따라서 위의 코드를 그대로 사용하면 NoUiqueBeanDefinitionException이 발생한다.

 

public class  OrderServiceImpl implements OrderService {

@Autowired
private PointPolicy ratePointPolicy;

...
}

 

이 경우 위와 같이 코드를 수정하면 @Autowired의 필드 명이 ratePointPolicy이므로 RatePointPolicy 클래스가 정상적으로 빈으로 매칭된다.

 


 

2. @Qualifier 사용하기

@Qualifier로 추가 구분자를 지정해 의존 관계 주입 시에 추가적인 옵션을 제공한다.

 

@Component로 등록 시에 @Qualifier를 사용해 옵션을 지정한다.

@Component
@Qualifier("fixPointPolicy")
public class FixPointPolicy implements PointPolicy {...}

@Component
@Qualifier("mainDiscountPolicy")
public class RatePointPolicy implements PointPolicy {...}

 

@Autowired로 의존 관계 주입 시에 @Qualifier로 호출할 빈을 설정한다.

@Autowired
public OrderServiceImpl(MemberRepository memberRepository, 
					@Qualifier("mainDiscountPolicy") PointPolicy pointPolicy) {
    this.memberRepository = memberRepository;
    this.pointPolicy = pointPolicy;
}

 


 

3. @Primary로 우선 순위를 지정하기

@Component로 빈 등록 시에 @Primary를 붙이면 @Autowired로 여러 빈이 매칭된 경우 @Primary가 붙은 빈이 우선권을 가지게 되고, 매칭된다.

 

@Component
public class FixPointPolicy implements PointPolicy {...}

@Component
@Primary
public class RatePointPolicy implements PointPolicy {...}