Argument Resolver 등록 관련 디버깅 (feat. Spring MVC 흐름)

결론: ArguemntResolver를 WebMvcConfigurer에 등록하지 않음
이글을 쓰는 이유는 MVC에 대한 이해도가 다소 높아진 게기가 되어서 작성했다
알게 된 바에 의하면
웹 요청이 있으면
Dispatcher Servlet -> Interceptor 목록 순회 -> Handler Adapter -> ArgumentResolver -> Handler (Controller
위와 같은 순서로 진행이 된다
조금 더 상세히 얘기하면
Dispatcher Servlet 를 거친 후 해당 요청 URL에 대한 Interceptor 목록을 순회한 후
Handler Adapter 목록을 조회 (대부분의 경우 RequetMappingHandlerAdapter)후
이동할 Handler에 대한 Argument목록 확인후 해석할 수 있는 ArguemntResolver목록을 조회한다
이때 커스텀 등록한 ArguemntResolver가 있으면 우선시 처리된다
그렇지 않다면 ModelAttributeProcess? 가 처리한다
현상
공연장 등록 POST 요청시 아래 에러 발생

이동할 URI

자세한 StackTrace
2023-06-20T12:28:28.998+09:00 INFO 8608 --- [nio-8080-exec-1] n.d.p.user.config.AuthInterceptor : access url: POST /venues
2023-06-20T12:28:35.608+09:00 ERROR 8608 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed: org.springframework.beans.BeanInstantiationException: Failed to instantiate [numble.deepdive.performanceticketingservice.user.domain.User]: Is it an abstract class?] with root cause
java.lang.InstantiationException: null
at java.base/jdk.internal.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48) ~[na:na]
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[na:na]
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480) ~[na:na]
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:211) ~[spring-beans-6.0.9.jar:6.0.9]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.constructAttribute(ModelAttributeMethodProcessor.java:335) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:222) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:85) ~[spring-webmvc-6.0.9.jar:6.0.9]
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:149) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:122) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:181) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:148) ~[spring-web-6.0.9.jar:6.0.9]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.0.9.jar:6.0.9]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.9.jar:6.0.9]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.9.jar:6.0.9]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.9.jar:6.0.9]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.9.jar:6.0.9]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.9.jar:6.0.9]
(Dispatcher Servlet 이후 로그만 남겨둠)
해석
User 객체를 생성하지 못하여 예외 발생
위 로그로 인한 코드 재 해색
HandlerAdapter구현체인 RequestMappingHandlerAdapter가 ModelAttributeMethodProcessor에게 ArgumentResolving를 위임


그러면 ModelAttributeMethoProcessor가 User 클래스를 생성하려고 시도한다
이 프로젝트의 경우 User는 두 구현체를 둔 abtract class 이기에 예외가 발생한다

해결
커스텀 ArguemntResolver를 잊지 말고 등록하자

