빈이 2개 이상일 때 생기는 오류
스프링에서는 같은 타입의 빈이 여러 개일 때, 어떤 빈을 사용할지 모호성이 발생합니다.
예를 들어 @Autowired 는 타입으로 빈을 조회하기 때문에 interface 가 discountPolicy 인 구현체가 2개 이상이라면 오류가 발생합니다. 당연하게도 discountPolicy 로 만든 구현체가 하나여야 하는데 2개 이상이라서 어떤 구현체를 불러와야 할지 모르기 때문입니다.
@Component
public class FixDiscountPolicy implements DiscountPolicy {}
@Component
public class RateDiscountPolicy implements DiscountPolicy {}
@Autowired
private final DiscountPolicy discountPolicy; // NoUniqueBeanDefinitionException 오류
이를 해결하기 위해 타입 매칭후 추가 조건을 지정하는 방법들을 제공합니다.
해결 방법
1. @Autowired 필드명 매칭
2. @Qualifier → @Qualifier 끼리 매칭 → 빈 이름 매칭
3. @Primary 사용
@Autowired 필드명 매칭
@Autowired 는 타입 매칭을 시도하고, 이때 여러 빈이 있으면 필드 이름, 파라미터 이름으로 빈 이름을 추가 매칭합니다.
@Autowired
private DiscountPolicy discountPolicy;
↓
private DiscountPolicy RateDiscountPolicy;
필드 명 매칭은 먼저 타입 매칭을 시도하고 그 결과에 여러 빈이 있을 대 추가로 동작하는 기능입니다.
@Qualifier
추가 구분자를 붙여주는 방법입니다.
주입 시 추가적인 방법을 제공하는 것이지 빈 이름을 변경하는 것은 아닙니다.
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements discountPolicy {}
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements discountPolicy {}
// 다른곳에서 주입
@Autowired
public OrderServiceImpl(@Qualifier("mainDiscountPolicy") DiscountPolicy discountPolicy)
@Primary
우선순위를 정하는 방법입니다.
@Autowired 시에 여러 빈이 매칭되면 @Primary 가 우선권을 가집니다.
@Component
@Primary
public class RateDiscountPolicy implements discountPolicy {}
@Component
public class FixDiscountPolicy implements discountPolicy {}
// 후에 의존성 주입
@Autowired
public OrderServiceImpl(DiscountPolicy discountPolicy) { // ... }
@Primary, @Qualifier 활용
코드에서 자주 사용하는 메인 데이터베이스의 커넥션을 획득하는 스프링 빈이 있고, 코드에서 특별한 기능으로 가끔 사용하는 서브 데이터베이스의 커넥션을 획득하는 스프링 빈이 있다고 가정할 때 메인 데이터베이스의 커넥션을 획득하는 스프링 빈은 @Primary 를 적용해서 조회하는 곳에서 @Qualifier 지정 없이 편리하게 조회하고, 서브 데이터베이스 커넥션 빈을 획득할 때는 @Qualifier 를 지정해서 명시적으로 획득하는 방식으로 사용하면 코드를 깔끔하게 유지할 수 있습니다.
우선순위
@Primary 는 기본값처럼 동작하는 것이고, @Qualifier 는 매우 상세하게 동작하게 됩니다.
이런 경우 스프링은 자동보다는 수동이, 넓은 범위의 선택권 보다는 좁은 범위의 선택권이 우선순위가 높습니다. 따라서 여기서도 @Qualifier 가 우선권이 높습니다.
'Spring' 카테고리의 다른 글
JSON 형태로 객체 반환하기 (1) | 2025.01.15 |
---|---|
빈 생명주기 콜백 (1) | 2025.01.09 |
다양한 의존관계 주입 방법 (1) | 2025.01.07 |
Spring 웹 애플리케이션 계층구조 (3) | 2024.12.23 |
Spring - @Value (3) | 2024.12.20 |