티끌모아 로키산맥 🏔
search
로ᄏl
배움에 끝은 없다... 개발 또한 그러하다.
Today
Yesterday
[Spring] NoUniqueBeanDefinitionException 예외 해결방법
이 해결법을 모르는 것은 아니지만 이 현상을 자주 맞이하는게 아니다보니, 늘 쓰는방식만쓰고 지나갔던 기억이 있다.
이번 기회에 정리해두고 똑같은 상황을 맞이했을 때 조금 더 현명(?)하게 대처할 수 있도록 기록을 남긴다.
총 3가지 예외 해결방법이 있다.
Autowired는 우선적으로 타입 매칭을 시도하고 타입이 매칭되는 빈이 여러개라면 이름(파라미터 이름)으로 빈 이름을 매핑한다.
(필드명 매칭은 타입 매칭 결과가 1개뿐이라면 발생하지 않는다)
@Autowired
private FooComponent foo; // FooComponent 타입의 빈이 2개 이상이면, 빈 이름이 foo 빈을 매핑!
private final FooComponent foo;
// 주 생성자 or 롬복으로 만든 생성자 주입 방식도 동일하다
public FooClass(FooComponent foo) {
this.foo = foo
}
@Qualifier 라는 추가 구분자를 붙여줌으로써 빈을 구분짓는 방법이다.
(실제로 빈 이름을 변경하는 것은 아니다)
만약 @Qualifier 주입을 할 때, value의 값에 매칭되는 Bean을 찾지 못하면 어떻게 될까? 그러면 value로 입력한 값과 일치하는 스프링 빈을 추가로 찾는다(@Qualifier는 추가적인 식별 방식이지 실제로 빈 이름을 변경하는 작업은 아니라고 언급했었다).
만약 그럼에도 일치하는 Bean을 찾지 못한다면 NoSuchBeanDefinitionException 예외가 발생한다.
하지만 @Qualifier는 @Qualifier를 찾는 용도로만 쓰는 것이 명확하고 좋다.
우선순위를 정하는 방법이다.
@Autowired 시에 여러 빈이 매칭되면 @Primary가 우선권을 가진다.
(@Primary 자체가 빈을 생성하기위한 애너테이션은 아니고, 빈 생성을 위한 애너테이션을 동일하게 붙여줘야한다)
@Component
@Primary
public class MainFooComponent implements FooComponent { } // 우선권을 가진다
@Component
public class NormalFooComponent implements FooComponent { }
만약 @Primary와 @Qualifier가 둘 다 있다면 어느 것이 먼저 동작하는가?
@Qualifier가 우선 순위가 높다!
(영한님 왈) 자세한 것이 우선권을 가져간다!
사실 같은 타입에 대해서 빈이 여러개 존재하고, 이 중 하나의 빈만 가지고와서 사용한 케이스가 생각보다 별로 없었던 것 같다. 🤔
이런 케이스에 대해서 Primary를 쓸 것인가 @Qualifier를 쓸 것인가에 대한 고민이 생길 수 있을 것 같다.
확실하게 Main인 빈이 확실한 경우라면 Primary도 충분히 고려해볼 수 있겠지만 아니라면 @Qualifier를 써야하지 않을까?
코틀린 스프링에서의 이벤트 처리 (with 유스콘) (0) | 2022.01.12 |
---|---|
[Spring] 싱글톤 레지스트지와 Bean Scope (0) | 2021.12.12 |
Spring - 의존성 주입(DI)을 '생성자 주입 방식'으로 권장하는 이유 (0) | 2020.12.20 |
스프링의 특징과 의존성 주입 (0) | 2020.03.15 |
@Get, @Post, Delete, @Put, @Patch Mapping (0) | 2020.01.09 |