Java & Spring Boot

스프링 빈 중복 에러 해결하기

둘기덕 2023. 3. 7. 19:05
반응형

스프링 프로젝트를 진행하다 보면, 우연히 두 개 이상의 빈(bean) 타입이 중복되는 경우가 발생할 수 있습니다. 이런 경우에는 NoUniqueBeanDefinitionException 에러가 발생하여 어떠한 빈이 중복되었는지 알려줍니다.

! 문제 상황 발생 !

그렇다면, 해당 에러가 발생했을 때는 어떠한 해결책이 있을까요? 우선 문제가 발생하는 상황의 예시를 봅시다.

 

[그림 1-1] 스프링 빈 중복

같은 타입의 이름이 다른 두 개의 빈을 등록하였습니다. 등록할 때는 문제가 되지 않습니다. 에러가 발생하는 것은 실제로 해당 타입의 빈이 사용이 될 때입니다. 다음 예제를 볼까요?

 

[그림 1-2] 스프링 빈 중복으로 인해 에러 발생

스프링 부트 입장에서는 참 난감합니다. 같은 타입의 빈이 두 개가 있는데, 어떤 의존성을 주입하라는 건지 알 수가 없습니다. 불쌍한 스프링 부트를 위해 이 에러를 해결해 줍시다.

1. 빈 이름 변경하기

당연하게도, 가장 간단한 해결 방법은 빈 이름을 변경하는 것입니다. 다음과 같이 이름을 변경해 봅시다.

 

[그림 2-1] 중복된 빈의 이름을 변경

첫 번째 메서드의 이름을 myDuck에서 duck으로 변경하였습니다. 이제 스프링 부트는 같은 이름의 빈을 찾았으니 더 이상 고민할 필요가 없게 되었습니다.

 

혹은, 빈 어노테이션에 이름을 명시할 수도 있습니다. 그림 2-2를 봅시다.

 

[그림 2-2] 빈 어노테이션을 사용하여 이름 변경

메서드 이름은 그대로 두고 빈 어노테이션에 이름을 명시하였습니다. 어떤 방식을 사용하던지 간에 빈 중복으로 인한 에러를 해결할 수 있습니다.

2. @Qualifier 어노테이션 사용하기

@Qualifier 어노테이션을 사용하면 동일한 타입의 빈이 여러 개일 때 구분할 수 있습니다. 생성자, setter 메서드, 혹은 필드 등 빈이 주입되는 어느 곳에서나 @Qualifier 어노테이션을 사용할 수 있습니다.

 

[그림 3-1] @Qualifier 사용

그리고 의존성을 주입하는 부분에 @Qualifier 어노테이션을 이용하여 어떤 빈을 사용할 건지 명시합시다.

 

[그림 3-2] @Qualifier 사용하여 특정 빈 명시

3. @Primary 어노테이션 사용하기

@Primary 어노테이션을 사용하면 여러 개의 빈 중에서 우선적으로 주입할 빈을 선택할 수 있습니다.

단, Qualifier와 Primary가 동시에 사용될 때는 Qualifier가 우선권을 가져간다는 것에 주의합시다.

 

[그림 4-1] @Primary 사용

어떤 방법이 가장 좋은가?

같은 타입의 빈이 여러 개 존재하고 각각의 상황마다 특정한 빈을 선택해야 하는 경우, @Qualifier 어노테이션을 사용하는 것이 좋습니다. 이를 통해 사용할 빈을 지정하여 빈 선택을 효과적으로 제어할 수 있습니다.

 

또는, 가장 높은 우선순위를 주고 싶은 빈이 있다면 @Primary 어노테이션을 사용하는 것이 좋습니다. 이를 통해 구성이 단순해지고 디폴트 값으로 빈을 제어할 수 있습니다.

 

기본 빈에 @Primary를 사용하고 서브 빈에 @Qualifier를 사용하는 방법도 있습니다. 애플리케이션 설계와 요구사항에 따라 최적의 방법이 달라지므로 상황에 따라 유연하게 사용하는 것이 좋습니다.

참고

반응형