Spring

ArgumentResolver의 작동 원리: Spring MVC에서 파라미터 처리 흐름과 활용 방법

백엔드 유성 2023. 7. 31. 19:18

이 글에서는 HTTP 요청에서부터 ArgumentResolver가 어디서 작동하는지 전반적인 흐름과 원리를 살펴보려 합니다.

저는 흐름을 알고 난 후 개발, 디버깅, 최적화 하는데 훨신 도움이 많이되어서 해당 파트를 넣었습니다.

 

만일 ArgumentResolver의 작동 방식에만 관심이 있으시다면, 3번으로 이동하셔도 좋습니다.

그리고 ArgumentResolver를 이용한 개발은 아래 url을 참고해주세요.

개발 : https://youseong.tistory.com/23


구체적인 내용은 다음과 같은 순서로 구성되어 있습니다:

1. ArgumentResolver를 이용한, 자주 사용되는 주요 어노테이션

2. 요청부터 응답까지: HTTP 요청의 전체 흐름
3. ArgumentResolver의 동작 원리

아래로 스크롤하면서 자세한 내용을 살펴보세요!


1. ArgumentResolver를 이용한 자주 사용하는 주요 어노테이션

스프링에서 우리가 자주 사용하는 ArgumentResolver를 이용한 어노테이션들은 다음과 같습니다.

  • @Requestparam
  • @RequestBody
  • @CookieValue

이러한 어노테이션들은 스프링을 처음 공부할 때, 메서드의 파라미터에 원하는 값이 자동으로 들어와서 신기했던 경험이 있네요.

이것들이 모두 ArgumentResolver를 기반으로 만들어진 어노테이션입니다.

 

 

2. HTTP 요청의 전체적인 처리 흐름

그림을 이용해 전체 흐름과 ArgumentResovler가 언제 동작하는지 확인해보겠습니다.

1. 클라이언트(브라우저)가 서버로 HTTP 요청을 보냅니다.
2. 서블릿 컨테이너가 이 요청을 받아 HttpServletRequest와 HttpServletResponse 객체를 만듭니다.
3. 이 객체들은 DispatcherServlet 로 전달됩니다.

4. DispatcherServlet는 HandlerMapping을 통해 요청 URL에 해당하는 Controller를 찾습니다.

5. DispatcherServlet은 RequestMappingHandlerAdapter로부터 ArgumentResolver를 받아 Controller내의 파라미터에 값을 할당합니다.
6. 이제 DispatcherServlet는 Controller를 실행합니다.

  - RestController를 사용하는 경우, 단순히 값이 반환됩니다.
  - 일반 Controller를 사용하는 경우, DispatcherServlet은 ViewResolver에게 View를 요청하고 결과를 반환받아 리턴합니다.
7. return된 결과는 DispatcherServlet에서 HttpServletResponse 객체에 담겨 클라이언트에게 전송됩니다.

 

HTTP 요청의 전체적인 흐름이였습니다.

여기서는 DispatcherServlet과 url 맵핑 부분, 파라미터 바인딩 부분을 자세하게 보았습니다.

 

 

3. ArgumentResolver 동작 원리

HandlerMethodArgumentResolver는 Spring MVC에서 제공하는 인터페이스로, 컨트롤러의 메서드에서 특정 조건에 맞는 파라미터가 있을 경우 이를 해석하여 원하는 값을 바인딩해주는 역할을 합니다.

HandlerMethodArgumentResolver는 supportsParameter와 resolveArgument 두 개의 메서드를 정의하고 있습니다.

1. supportsParameter: 이 메서드는 컨트롤러의 특정 파라미터를 ArgumentResolver가 지원하는지 여부를 판단하는 역할을 합니다. 만약 true를 반환하면 해당 ArgumentResolver의 resolveArgument 메서드가 실행됩니다.

UserCache라는 어노테이션이 달려있고, 파라미터 타입이 String인 경우

2. resolveArgument: 이 메서드는 실제로 파라미터의 값을 리턴하는 역할을 합니다. 이 값을 반환하면 DispatcherServlet은 이 값을 해당 파라미터에 바인딩합니다.

이런 방식으로 ArgumentResolver는 매우 유연하게 컨트롤러 메서드의 파라미터를 다루는 데 도움이 됩니다. 특히 동일한 로직이 여러 컨트롤러에 걸쳐 반복되는 경우 이를 ArgumentResolver에 정의함으로써 코드의 중복을 줄이고 코드의 가독성과 유지보수성을 향상시킬 수 있습니다.

 

4. 장/단점과 주의사항

장점

  • 공통적으로 사용되는 코드를 재사용 할 수 있습니다. 예를들어 Session, Cache, 인증 등의 값을 추출을 여러 컨트롤러에 걸쳐서 사용된다면 코드 양을 줄일 수 있습니다.
  • 코드가 간결해집니다. 위와 같은 이유로 코드가 간결해집니다.

단점

  • 복잡성이 증가합니다. 편이성이 많은것은 맞지만, 해당 기능이 어떤 역할을 하는지 모호하다면, 어떤 파라미터를 지원하는지 그리고 어떤 로직이 수행되는지 이해하는 데 시간이 필요하게됩니다. 이럴 경우 차라리 ArgumentResolver를 안 쓰는 것이 더 좋다고 생각합니다.

주의할점

  • ArgumentResolver에는 비즈니스 로직이 포함되지 않도록 해야합니다. 필요한 값을 읽어오는 정도가 적당하다고 생각합니다.
  • 예외가 발생하면 DispatcherServlet이 처리를 중단하고 예외를 던지므로 적절한 예외 처리 방식을 고려해야 합니다.
  • HandlerMethodArgumentResolver를 상속받아서 ArgumentResolver를 구현했으면 WebMvcConfigurer 에 등록해야 사용이 가능합니다.


추가로 ArgumentResolver를 이용하여 Custom Argument Resolver를 만드는 과정을 보고싶으신 분은 아래 링크를 확인해주세요.

 

https://youseong.tistory.com/23

 

파라미터 어노테이션 만들기 with ArgumentResolver

소스코드: GitHub - youseonghyeon/argument-resolver Contribute to youseonghyeon/argument-resolver development by creating an account on GitHub. github.com spring web의 Controller에서 인증 정보나 헤더 를 가져와야 할 경우가 있습니다

youseong.tistory.com

 

읽어주셔서 감사합니다!