[Spring]스프링 부트 중복으로 빈을 등록했을때 해결 방법(@Autowired, @Qualifier, @Primary)
코드 예
public interface DiscountPolicy {
//코드
}
@Component
public class FixDiscountPolicy implements DiscountPolicy {
//코드
}
@Component
public class RateDiscountPolicy implements DiscountPolicy {
//코드
}
@ComponentScan
public class Config {
코드
}
@ComponentScan을 사용하면 @Component 어노테이션이 붙은 클래스들을 스프링 빈으로 등록하게 됩니다.
등록하게 되면 스프링 컨테이너의 스프링 빈에 등록되는 것은 클래스들의 타입이 스프링 컨테이너에 빈으로 등록됩니다.
여기서 사용된 DI는 생성자 주입 방식입니다. (DI 종류 : 생성자 주입, 필드 주입, 수정자(setter) 주입)
@Component
public class OrderServiceImpl implements OrderService {
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
생성자 주입 방식에서 매개변수로 DiscountPolicy타입이 들어가 있습니다.
그럼 아래 오류 처럼 오류가 발생할 것이다
*오류 내용
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'orderServiceImpl' defined in file [경로]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'hello.core.discount.DiscountPolicy' available: expected single matching bean but found 2: fixDiscountPolicy,rateDiscountPolicy |
왜냐하면 DiscountPolicy 타입인 RateDiscountPolicy와 FixDiscountPolicy가 중복으로 등록되어 있기 때문입니다.
오류 내용도 함께 확인해보면 마지막 줄에
expected single matching bean but found 2: fixDiscountPolicy, rateDiscountPolicy
라는 오류가 발생하여 어떤 오류인지는 확인하기 쉬울 것입니다.
빈이 중복으로 등록되었을때 해결 방법 3가지
1. @Autowired
2. @Qualifier
3. @Primary
1. Autowired
- 생성자 주입에서 매개변수로 있는 변수 이름을 변경해주면 됩니다.
@Component
public class OrderServiceImpl implements OrderService {
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(DiscountPolicy rateDiscountPolicy) {
this.discountPolicy = rateDiscountPolicy;
}
discountPolicy -> rateDiscountPolicy로 변경을 해주면 RateDiscountPolicy가 등록이 됩니다.
그 이유는 스프링 빈으로 등록될 때 RateDiscountPolicy이 rateDiscountPolicy로 등록이 되기 때문입니다.
만약 FixDiscountPolicy를 등록하고 싶으면 fixDiscountPolicy로 변경하면 됩니다.
@Qualifier
@Component
@Qualifier("fixDiscountPolicy")
public class FixDiscountPolicy implements DiscountPolicy {
//코드
}
@Component
@Qualifier("mainDiscountPolicy")
public class RateDiscountPolicy implements DiscountPolicy {
//코드
}
@Component
public class OrderServiceImpl implements OrderService {
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(@Qualifier("fixDiscountPolicy") DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
DiscountPolicy를 구현하고 있는 구현체 클래스에 @Qualifier("이름")을 설정해주면 됩니다.
여기서 "이름" 이 부분에 적히는 이름이 스프링 빈에 저장되는 것이 아닙니다.
이해하기 쉽게 설명하자면 별명 같은 거라고 생각하면 쉽습니다.
구현체 클래스에 @Qualifier("이름")를 설정해줬으면 생성자 주입 매개변수 타입 앞에 똑같이 적어줍니다.
@Qualifier("fixDiscountPolicy") DiscountPolicy discountPolicy를 하게 되면 FixDiscountPolicy가 빈에 등록됩니다.
RateDiscountPolicy를 등록하고 싶으면 fixDiscountPolicy -> mainDiscountPolicy로 변경해주면 됩니다.
@Primary
- @Primary 어노테이션 붙은 구현체가 우선순위가 됩니다.
@Component
public class FixDiscountPolicy implements DiscountPolicy {
//코드
}
@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {
//코드
}
@Component
public class OrderServiceImpl implements OrderService {
private final DiscountPolicy discountPolicy;
@Autowired
public OrderServiceImpl(DiscountPolicy discountPolicy) {
this.discountPolicy = discountPolicy;
}
RateDiscountPolicy 구현체에 @Primay 어노테이션을 쓰게 되면 RateDiscountPolicy의 우선순위가 제일 높아서
생성자 주입에는 @Primary가 붙은 RateDiscountPolicy가 들어가게 되면서 빈에는 RateDiscountPolicy가 등록이 됩니다. FixDiscountPolicy가 RateDiscountPolicy보다 우선순위를 높게 하고 싶으면 RateDiscountPolicy에 있는 @Primary를 지우고 FixDiscountPolicy에 붙이면 됩니다.
'Spring Boot' 카테고리의 다른 글
[Spring] @ScriptAssert 오류내용 및 해결방법 (0) | 2021.12.28 |
---|---|
[Spring] 메시지, 국제화 개념 및 사용 방법 (0) | 2021.12.26 |
[Spring]@RestController, @Controller 개념 및 예시 (0) | 2021.12.19 |
[Spring]싱글톤 패턴의 개념 및 예제 (0) | 2021.11.19 |
[Spring]스프링부트 H2 데이터베이스 연동 오류 (2) | 2021.11.01 |
댓글
이 글 공유하기
다른 글
-
[Spring] 메시지, 국제화 개념 및 사용 방법
[Spring] 메시지, 국제화 개념 및 사용 방법
2021.12.26 -
[Spring]@RestController, @Controller 개념 및 예시
[Spring]@RestController, @Controller 개념 및 예시
2021.12.19 -
[Spring]싱글톤 패턴의 개념 및 예제
[Spring]싱글톤 패턴의 개념 및 예제
2021.11.19 -
[Spring]스프링부트 H2 데이터베이스 연동 오류
[Spring]스프링부트 H2 데이터베이스 연동 오류
2021.11.01