-
카테고리
-
세부 분야
백엔드
-
해결 여부
미해결
V2 ConcreteProxyController 빈 중복 에러 (SpringBoot V3)
23.06.28 22:39 작성 23.06.30 15:18 수정 조회수 370
0
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오) 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예
[질문 내용]
안녕하세요, 영한님! 먼저 이렇게 좋은 강의를 들을 수 있게 되어서 너무 기쁘고 감사드립니다.
먼저 저는 SpringBoot 3.0.5 버전 사용중입니다.
그렇기 때문에 어쩔 수 없이 @RequestMapping으론 컴포넌트 스캔 대상이 되지 않기 때문에 V2 컨트롤러에는 @RestController가 붙어있습니다.
구체 클래스 기반 프록시 V2에 적용할 때, 프록시 컨트롤러를 빈으로 등록하려고 하니 아래처럼 빈이 중복으로 등록된다고 오류가 발생하였습니다.
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'orderControllerV2', defined in class path resource [me/iseunghan/hello/proxy/app/v2/concrete_proxy/ConcreteProxyConfig.class], could not be registered. A bean with that name has already been defined in file [/Users/iseunghan/workspaces/study/lecture-spring-advanced/proxy/build/classes/java/main/me/iseunghan/hello/proxy/app/v2/OrderControllerV2.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
Process finished with exit code 1
그래서 로그에 친절하게 나와있는대로 application.yaml에 아래 설정을 추가하니 정상적으로 실행 및 테스트가 되었습니다.
application.yaml
spring.main.allow-bean-definition-overriding: true
혹시 이와 같은 방법 이외에는 다른 방법이 없을지 여쭤보고 싶습니다..! 감사합니다.
답변을 작성해보세요.
0
i seunghan
질문자2023.07.25
안녕하세요, 답변 감사드립니다. 하지만 뭔가 명확한 답변을 못받아 다시 질문 드립니다..
일단 제가 생각한 빈이 중복된 이유는 다음과 같습니다.
@RestController가 붙어있는 클래스가 먼저 빈으로 등록
@Configuration 내부에 @Bean으로 등록하려는 빈이 이미 1번에서 등록이 되어 중복 등록에 대한 오류가 생긴 것 입니다.
스프링부트 버전 3 이상에서는 인터페이스에 @RestController를 붙여줘야만 컨트롤러로 인식하여 구현체가 구현했을 때 엔드포인트 매핑이 된다는 것입니다.
현재 강의에서는 인터페이스 기반 프록시를 구현중이라 어쩔수 없이 컨트롤러 코드에 @RestController를 붙여야 하는 상황인데.. @RestController를 제거하면 URLMapping이 정상적으로 이루어지지 않습니다.. 이럴 때에는 어떻게 하면 좋을지 궁금합니다.
아래 코드 첨부드립니다.
@RequiredArgsConstructor
@RestController
public class OrderControllerV2 {
private final OrderServiceV2 orderService;
@GetMapping("/v2/request")
public String request(String itemId) {
orderService.orderItem(itemId);
return "ok";
}
@GetMapping("/v2/no-log")
public String nolog() {
return "ok";
}
}
public class OrderControllerConcreteProxy extends OrderControllerV2 {
private final OrderControllerV2 target;
private final LogTrace logTrace;
public OrderControllerConcreteProxy(OrderControllerV2 target, LogTrace logTrace) {
super(null);
this.target = target;
this.logTrace = logTrace;
}
@Override
public String request(String itemId) {
TraceStatus status = null;
try {
status = logTrace.begin(this.getClass().getSimpleName() + ".save()");
String response = target.request(itemId);
logTrace.end(status);
return response;
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
@Override
public String nolog() {
TraceStatus status = null;
try {
status = logTrace.begin(this.getClass().getSimpleName() + ".save()");
String response = target.nolog();
logTrace.end(status);
return response;
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
}
@Configuration
public class ConcreteProxyConfig {
@Bean
public OrderRepositoryV2 orderRepositoryV2(LogTrace logTrace) {
OrderRepositoryV2 orderRepositoryV2 = new OrderRepositoryV2();
return new OrderRepositoryConcreteProxy(orderRepositoryV2, logTrace);
}
@Bean
public OrderServiceV2 orderServiceV2(LogTrace logTrace) {
OrderServiceV2 orderServiceV2 = new OrderServiceV2(orderRepositoryV2(logTrace));
return new OrderServiceConcreteProxy(orderServiceV2, logTrace);
}
@Bean
public OrderControllerV2 orderControllerV2(LogTrace logTrace) {
OrderControllerV2 orderControllerV2 = new OrderControllerV2(orderServiceV2(logTrace));
return new OrderControllerConcreteProxy(orderControllerV2, logTrace);
}
}
@Import(ConcreteProxyConfig.class)
@SpringBootApplication(scanBasePackages = {"me.iseunghan.hello.proxy.app.v2"})
public class ProxyApplication {
public static void main(String[] args) {
SpringApplication.run(ProxyApplication.class, args);
}
@Bean
public LogTrace logTrace() {
return new ThreadLocalLogTrace();
}
}
패키지 구조
0
인프런 AI 인턴
2023.06.30
안녕하세요, 인프런 AI 인턴입니다.
중복으로 빈이 등록된 오류가 발생했다는 내용이군요. 이러한 오류는 동일한 이름의 빈이 여러 곳에서 중복으로 등록되었을 때 발생합니다.
오류 메시지를 보면 orderControllerV2
라는 이름의 빈이 ConcreteProxyConfig.class
와 OrderControllerV2.class
에 중복으로 등록되었다고 나와있습니다.
이러한 경우, 스프링은 이름이 같은 두 개의 빈을 구분하지 못해 오류가 발생하게 됩니다. 이 문제를 해결하기 위해서는 중복으로 등록된 빈 중 하나를 제거하거나, 빈의 이름을 변경하여 충돌을 피해야 합니다.
따라서, ConcreteProxyConfig.class
또는 OrderControllerV2.class
중 하나에서 빈을 제거하거나, 빈의 이름을 변경하실 수 있도록 해주시면 됩니다.
더 자세한 사항을 알고 싶으신 경우, 스프링의 빈 등록 규칙과 중복 등록되는 이유에 대해 공부해보시면 도움이 되실 것입니다.
더 궁금한 사항이 있다면 언제든지 물어보세요. 도움이 될 수 있도록 최선을 다하겠습니다.
답변 2