• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

인터페이스 기반 프록시 적용 후 orderController bean method 오류

23.05.08 23:06 작성 23.05.08 23:17 수정 조회수 627

1

학습하는 분들께 도움이 되고, 더 좋은 답변을 드릴 수 있도록 질문전에 다음을 꼭 확인해주세요.

1. 강의 내용과 관련된 질문을 남겨주세요.
2. 인프런의 질문 게시판과 자주 하는 질문(링크)을 먼저 확인해주세요.
(자주 하는 질문 링크: https://bit.ly/3fX6ygx)
3. 질문 잘하기 메뉴얼(링크)을 먼저 읽어주세요.
(질문 잘하기 메뉴얼 링크: https://bit.ly/2UfeqCG)

질문 시에는 위 내용은 삭제하고 다음 내용을 남겨주세요.
=========================================
[질문 템플릿]
1. 강의 내용과 관련된 질문인가요? (예/아니오) 예
2. 인프런의 질문 게시판과 자주 하는 질문에 없는 내용인가요? (예/아니오) 예
3. 질문 잘하기 메뉴얼을 읽어보셨나요? (예/아니오) 예

[질문 내용]
인터페이스 프록시를 적용한 뒤 프로젝트를 실행 하니 아래와 같은 오류가 발생했습니다.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'orderControllerImpl' method 
hello.proxy.app.config.v1_proxy.interface_proxy.OrderControllerInterfaceProxy#request(String)
to {GET [/v1/request]}: There is already 'orderControllerV1' bean method
hello.proxy.app.v1.OrderControllerV1Impl#request(String) mapped.

검색해보니 매핑 정보가 겹쳐있다고 나오는데

제가 보기에는 어디가 겹친 건지 모르겠더라구요..

강의 코드도 비교 해봤는데 비슷한거 같고..

어디가 문제인지 궁금합니다.

해당 오류가 발생한 OrderControllerInterfaceProxy와 OrderControllerV1Impl 코드 첨부합니다.

  • ProxyApplication

@Import(InterfaceProxyConfig.class)
@SpringBootApplication(scanBasePackages = "hello.proxy.app") // app 패키지 하위만 컴포넌트 스캔의 대상이 된다.
public class ProxyApplication {

	public static void main(String[] args) {
		SpringApplication.run(ProxyApplication.class, args);
	}

	@Bean
	public LogTrace logTrace() {
		return new ThreadLocalLogTrace();
	}

}
  • OrderControllerInterfaceProxy

@RequiredArgsConstructor
public class OrderControllerInterfaceProxy implements OrderControllerV1 {

    private final OrderControllerV1 target;
    private final LogTrace logTrace;

    @Override
    public String request(String itemId) {
        TraceStatus status = null;
        try {
            status = logTrace.begin("OrderController.request()");
            // target 호출
            String result = target.request(itemId);
            logTrace.end(status);
            return result;
        } catch (Exception e) {
            logTrace.exception(status, e);
            throw e;
        }
    }

    @Override
    public String noLog() {
        return target.noLog();
    }
}

 

  • OrderControllerV1Impl

@Slf4j
public class OrderControllerV1Impl implements OrderControllerV1 {
    private final OrderServiceV1 orderService;

    public OrderControllerV1Impl(OrderServiceV1 orderService) {
        this.orderService = orderService;
    }

    @Override
    public String request(String itemId) {
        orderService.orderItem(itemId);
        return "OK";
    }

    @Override
    public String noLog() {
        return "OK";
    }
}

 

  • OrderControllerV1 (인터페이스)

@RequestMapping("/v1") // 스프링은 @Controller 또는 @RequestMapping 이 있어야 스프링 컨트롤러로 인식한다. (수동 등록 사용으로 @Controller 사용 안함)
@ResponseBody
public interface OrderControllerV1 {

    @GetMapping("/request")
    String request(@RequestParam("itemId") String itemId);

    @GetMapping("/no-log")
    String noLog();
}

답변 2

·

답변을 작성해보세요.

0

안녕하세요. HH님

package의 위치가 잘못 지정되어 있습니다. 다음에 설명하는 내용과 같이 수정 위치로 이동해주세요.

현재 위치

hello.proxy.app.config

수정 위치

hello.proxy.config

config 하위 내용은 컴포넌트 스캔의 대상이 되면 안됩니다. 그런데 패키지 위치가 잘못 되어서 모두 컴포넌트 스캔이 되어서 빈들이 다 등록이 되고 있습니다.

감사합니다.

HH님의 프로필

HH

질문자

2023.05.14

답변 감사합니다 !

제가 config 패키지를 생성하는 위치를 착각해서 proxy.app 하위에 config 패키지를 생성해

@Import로 app.config.InterfaceProxyConfig.class 빈 설정파일을 빈 등록한 것과

컴포넌트 스캔으로 hello.proxy.app 하위 패키지들을 빈 등록한게 겹쳐서 발생한 문제였네요..

@Import(InterfaceProxyConfig.class)
@SpringBootApplication(scanBasePackages = "hello.proxy.app") 

조금 더 생각해서 보면 스스로 잡을 수 있는 오류였는데 부끄럽네요 하하...

지금까지 로드맵으로 기초부터 쭉 달리면서 현재 고급편과 스프링 - 핵심 원리 편을 남기고 있습니다.

로드맵의 순서대로 한 강의 한강의 완강할 때마다 복습을 하면서 점점 성장해 있는 자신을 보니 너무 뿌듯하고 재밌네요 ㅎㅎ

답변 감사드리며 좋은 강의 만들어주셔서 감사합니다 !

 

0

안녕하세요. HH님

전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx

주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요

추가로 다음 내용도 코멘트 부탁드립니다.

1. 실행 방법을 알려주세요.

2. 어떻게 문제를 확인할 수 있는지 자세한 설명을 남겨주세요.

감사합니다.

HH님의 프로필

HH

질문자

2023.05.12

업로드한 폴더 링크

업로드한 폴더의 링크 입니다.

https://drive.google.com/file/d/1dxDqzYjMLG0eBL6RHnRWoDI2JmVlytQa/view?pli=1

 

  • 실행 방법 : SpringBootApplication 파일을 실행 ( import한 설정 파일이 InterfaceProxyConfig.class 인 이후부터 오류 발생)

  • 문제 확인 방법 : InterfaceProxyConfig 를 import 한 뒤부터 아래의 매핑 오류가 발생합니다.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: Ambiguous mapping. Cannot map 'orderControllerImpl' method 
hello.proxy.app.config.v1_proxy.interface_proxy.OrderControllerInterfaceProxy#request(String)
to {GET [/v1/request]}: There is already 'orderControllerV1' bean method
hello.proxy.app.v1.OrderControllerV1Impl#request(String) mapped.

 


추가 질문

안녕하세요 강의 잘 보고 있습니다 !

다름이 아니라 위의 에러가 발생하고 원인을 찾지 못하겠어 질문을 올린뒤에 추가로

뒤에 강의 진도를 나갔는데, 프록시 팩토리를 이용한 설정 파일 ProxyFactoryConfigV1 이후 부터 아래의 오류가 발생합니다.

The bean 'orderControllerV2', defined in class path resource [hello/proxy/app/config/v1_proxy/ConcreteProxyConfig.class], could not be registered. A bean with that name has already been defined in class path resource [hello/proxy/app/config/AppV2Config.class] and overriding is disabled.

이 오류가 AppV2Config.class 빈 설정 파일을 통해 이미 스프링 컨테이너에 orderControllerV2를 등록해서 orderControllerV2를 또 등록할 수 없다는 오류로 알고 있는데

여기서 궁금한점이 있습니다.

만약 @Cofiguration을 붙인 수동 빈 설정 클래스들이 @import로 직접 지정하지 않아도 @Bean으로 빈등록이 되기 때문에 이러한 오류가 났다면 강의에서도 저와 같은 오류가 났었을텐데

@import로 설정파일 스캔 대상 클래스를 직접 지정했는데, 왜 이런 중복이 생기는지 모르겠습니다..