[Spring] HandlerMethodArgumentResolver 동작 원리

2023. 5. 7. 21:28· FRAMEWORK/[SPRING]
목차
  1. [Spring] HandlerMethodArgumentResolver 동작 원리
  2. 0. 들어가기 전에
  3. 1. HandlerMethodArgumentResolver란?
  4. 2. 동작 위치
  5. 3. 동작 과정
  6. ※ 참고

[Spring] HandlerMethodArgumentResolver 동작 원리

 

0. 들어가기 전에

ArugmentResolver을 사용해보고, 어느 시점에서 사용 되는지 알아보기 위해 정리했습니다.



1. HandlerMethodArgumentResolver란?

특정 조건에 맞는 파라미터가 있을 때 원하는 값을 바인딩해주는 인터페이스

 

컨트롤러에 있는 메서드 파라미터는 누가 넘겨주는 것일까? 우리는 @GetMapping, @PostMapping등이 붙은 메서드를 사용하면서, 메서드 파라미터 값에 @RequestParam, @RequestBody를 사용해서 값을 입력받는다. JSON을 파싱하고 파라미터에 값을 넣어주는 복잡한 연산들을 누가하는 것일까? 이 연산들을 하는 것은 흔히 얘기하는 ArgumentResolver 즉, HandlerMethodArgumentResolver가 한다.

HandlerMethodArgumentResolver는 영어 그대로 해석하자면 핸들러에 있는 메서드의 인자 확인자이다. 핸들러는 컨트롤러이고, 메서드 인자는 메서드 파라미터이므로 풀어서 말하자면 컨트롤러에 있는 메서드 파라미터를 결정해주는 역할을 하는 인터페이스가 된다.

우리가 자주 사용하는 @RequestParam, @RequestBody 모두 ArgumentResolver가 사용하는 어노테이션으로 각각 HandlerMethodArgumentResolver를 구현한 구현체들이 어노테이션에 맞게 파라미터 바인딩을 해준다.



2. 동작 위치

그림으로 설명하기 위해 지난번에 포스팅했던 DispatcherServlet 글의 동작과정 그림을 가져와 봤다.

DispatcherServlet의 동작을 더 집중하기 위해 ArgumentResolver의 동작을 생략했지만, 실제로 ArgumentResolver는 4번 동작 쯤에서 작동한다.

아래는 좀 더 자세히 나타낸 그림이다.

[순서]

  1. 컨트롤러를 처리하기 전에 어댑터는 ArgumentResolver에 요청을 해 컨트롤러에서 필요한 파라미터를 요청한다.
  2. ArgumentResolver는 Controller를 보고 파라미터를 찾는다.
  3. 핸들러 어댑터에게 파라미터를 반환한다.
  4. 핸들러 어댑터는 파라미터를 가지고 컨트롤러를 처리한다.
  5. 컨트롤러를 처리하고 결과 값을 HandlerMethodReturnValueHandler 인터페이스를 걸쳐서 처리한다.(ex) @ResponseBody, String, ModelAndView)
  6. -> 여기서 HandlerMethodReturnValueHandler를 통해서 반환하는 이유는 다양한 타입을 처리하기 위해서이다.

실제로 @RequestParam은 RequestParamMethodArgumentResolver가 동작하고, @ReqeustBody는 RequestResponseBodyMethodProcessor라는 HandlerArgumentResolver의 구현체들이 처리를 하게 된다.

이제 코드로 확인을 해보자.



3. 동작 과정

처음에 DispatcherServlet이 컨트롤러에서 @RequestMapping이 붙은 메서드의 정보를 보고, RequestMappingHandlerAdapter를 찾는다. 그 후 InvocableHandlerMethod를 실행해서 ArgumentResolver를 선택해 처리한다.

// InvocableHandlerMethod#invokeForRequest
@Nullable
public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
    Object... providedArgs) throws Exception {

  Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs); // 여기를 좀 더 자세히 살펴보자.
  if (logger.isTraceEnabled()) {
    logger.trace("Arguments: " + Arrays.toString(args));
  }
  return doInvoke(args);
}
// InvoableHandlerMethod#getMethodArgumentValues
protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

  // ...
  // 메서드 파라미터의 정보를 저장하는 클래스
    MethodParameter[] parameters = getMethodParameters();

  // ...

    Object[] args = new Object[parameters.length];
  for (int i = 0; i < parameters.length; i++) {

      // resolver가 여기서 작동하게 됨
      args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);

        // ...

  }  

  return args;
}

image-20230506235452855

this.resolvers은 HandlerMethodArgumentResolver의 구현체인 HandlerMethodArgumentResolverComposite로 되어 있다. 이 구현체에는 스프링에서 등록한 모든 ArgumentResolver를 들고있고, for문을 돌며 supportParameter()를 통해 적용할 수 있는 resolver를 선택해 처리하게 된다.




※ 참고

  • 스프링 MVC 1편 - 백엔드 웹 개발 핵심 기술
  • Class MethodParameter
  • Class InvocableHandlerMethod
저작자표시 (새창열림)

'FRAMEWORK > [SPRING]' 카테고리의 다른 글

LazyConnectionDataSourceProxy의 역할  (0) 2024.01.26
[Spring] Spring Rest docs 적용해보기  (1) 2023.05.21
[Spring] DispatcherServlet이란?  (0) 2023.04.27
[Spring] Spring에서 Bean은 어떤 자료구조로 관리될까요?  (0) 2023.04.22
[Spring] Spring에서 DI하는 3가지 방법  (1) 2023.04.21
  1. [Spring] HandlerMethodArgumentResolver 동작 원리
  2. 0. 들어가기 전에
  3. 1. HandlerMethodArgumentResolver란?
  4. 2. 동작 위치
  5. 3. 동작 과정
  6. ※ 참고
'FRAMEWORK/[SPRING]' 카테고리의 다른 글
  • LazyConnectionDataSourceProxy의 역할
  • [Spring] Spring Rest docs 적용해보기
  • [Spring] DispatcherServlet이란?
  • [Spring] Spring에서 Bean은 어떤 자료구조로 관리될까요?
쿠엔크
쿠엔크
우아한테크코스 5기 BE 에단 Github : https://github.com/cookienc
쿠엔크
기러기는 기록기록
쿠엔크
전체
오늘
어제
  • 분류 전체보기 (132)
    • CS (46)
      • [OS] (12)
      • [NETWORK] (10)
      • [DATABASE] (11)
      • [BASIC CONCEPT] (1)
      • [DATA STRUCTURE] (7)
      • [ALGORITHM] (5)
    • LANGUAGE (17)
      • [JAVA] (17)
    • DESIGN_PATTERN (2)
    • FRAMEWORK (18)
      • [SPRING] (18)
    • ORM (11)
      • JPA (11)
    • AWS (7)
    • BOOK (10)
      • [자바 웹 개발 워크북] (3)
      • [이펙티브 자바] (7)
    • 개발 (19)
      • [오류] (7)
      • [고민] (1)
      • [우테코] (10)
      • [iTracker] (1)
    • Tip (1)
      • [Plugins] (1)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • java
  • 개념
  • 오류
  • HTTP
  • CORS
  • 데이터베이스
  • aws
  • 네트워크
  • 운영체제
  • JVM
  • 디자인 패턴
  • 알고리즘
  • 가비아
  • 자바 웹 개발 워크북
  • JPA
  • ArgumentResolver
  • 자료구조
  • 스프링
  • Effective Java
  • Spring

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.2
쿠엔크
[Spring] HandlerMethodArgumentResolver 동작 원리

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.