실무에서 중복 Bean 에러를 만난 적이 있었는데요~
관련된 내용을 정리해보겠습니다!
문제 재현
우선 문제 재현을 위해서 spring initializer 에서 위와 같이 설정하여 프로젝트를 생성했습니다
먼저 Interface 를 정의합니다
package com.example.dupbean.service;
public interface RecommendService {
String getRecommendServiceName();
}
그리고 Interface 를 구현하는 두 가지 클래스의 Bean을 @Order 를 적용해서 만듭니다
package com.example.dupbean.service;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
@Order(1)
@Service
public class MockRecommendBO implements RecommendService {
@Override
public String getRecommendServiceName() {
return "mock";
}
}
package com.example.dupbean.service;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Service;
@Order(2)
@Service
public class LocalRecommendBO implements RecommendService {
@Override
public String getRecommendServiceName() {
return "local";
}
}
Interface 를 기준으로 Bean 을 가져와서 사용하는 부분을 구현합니다
package com.example.dupbean.controller;
import com.example.dupbean.service.RecommendService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class RecommendController {
private final RecommendService recommendService;
@GetMapping("/recommend/name")
public String getRecommendName() {
return recommendService.getRecommendServiceName();
}
}
실행해보면 아래와 같이 에러가 발생합니다
Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2025-02-22T16:32:55.299+09:00 ERROR 51647 --- [dupbean] [ restartedMain] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.example.dupbean.controller.RecommendController required a single bean, but 2 were found:
- localRecommendBO: defined in file [/Users/user/temp/playground/dupbean/build/classes/java/main/com/example/dupbean/service/LocalRecommendBO.class]
- mockRecommendBO: defined in file [/Users/user/temp/playground/dupbean/build/classes/java/main/com/example/dupbean/service/MockRecommendBO.class]
This may be due to missing parameter name information
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
bean 을 사용하는 부분에서는 single bean 을 사용하고 있는데, 실제로 bean 은 두 개가 있다는 내용의 에러입니다
@Order 어노테이션을 사용해서 bean 을 선택하려고 한 것이 문제죠!
결론
현업에서는 java.io.IOException: java.lang.reflect.InvocationTargetException 가 발생하는 경험을 했었는데요
회사에서 경험한 것을 자세히 공유하기는 어렵지만, 아마 원인은 비슷할 것이라고 생각합니다
애시당초 @Order 어노테이션은 같은 타입의 bean 들의 순서를 지정할 뿐 bean 을 선택하는 기준을 설정하는 것은 아닙니다
그러므로 위 에러 메시지의 Action: 하위 내용처럼 @Primary 나 @Qualifier 를 사용하는 것이 좋습니다
그런데 개인적으로는 아래와 같이 Bean의 우선순위를 구분할 때에는 Annotation 보다는 아래와 같이 모든 Bean을 가져온 다음에 Factory 패턴을 편이 더 좋을 것 같습니다 🤔
private final List<RecommendService> recommendServiceList;
물론 잠깐의 테스트를 위한 Bean 들이라면 @Primary 를 사용하거나 주석처리하는 것이 훨씬 편리할 것 같습니다 😁
'소프트웨어' 카테고리의 다른 글
오픈소스 컨트리뷰션 후기 (0) | 2024.01.14 |
---|---|
코딩 없이 Next.js 기반 블로그 만들기 (0) | 2023.12.20 |
java.lang.NoClassDefFoundError: com/querydsl/apt/AbstractQuerydslProcessor 에러 해결 (0) | 2023.12.16 |
ChatGPT 장애 (Oops! Our systems are ...) (0) | 2023.11.23 |
java.lang.UnsupportedOperationException 발생 케이스 (2) | 2022.12.31 |