Back-end/Spring Boot, JPA

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

philo0407 2023. 6. 20. 20:33

 

https://unsplash.com/ko/%EC%82%AC%EC%A7%84/HsTnjCVQ798

 

결론: 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를 잊지 말고 등록하자