1. 핵심 개념

 Spring MVC에서 HTTP 요청을 처리할 때, 요청의 파라미터를 메서드 인자로 변환하는 역할
 일반적으로 컨트롤러 메서드에서 요청 파라미터를 처리하기 위해 사용
 HandlerMethodArgumentResolver를 확장하여 구현하며, 이를 통해 커스텀 인자 변환을 처리

* HandlerMethodArgumentResolver: 
Spring MVC의 @RequestMapping 메서드나 기타 핸들러 메서드의 매개변수를 자동으로 변환하는 인터페이스

2. 동작 원리

더보기

사용자가 웹 브라우저를 통해 요청하면 DispatcherServlet이 이를 받음

> DispatcherServlet은 해당 요청에 맞는 URI를 HandlerMapping에서 검색

> 이 때, RequestMapping으로 구현한 API를 찾게 되는데, 이들은 RequestMappingHandlerAdapter가 모두 가지고 있음

> 원하는 Mapping을 찾은 경우, 첫 번째로 Intercepter를 처리

> Argument Resolver 처리

> Message Converter 처리

> Controller Method Invoke

1.	클라이언트 요청: 
	클라이언트가 HTTP 요청을 보내면, Spring MVC는 요청 파라미터를 컨트롤러 메서드의 인자로 변환준비
2.	ArgumentResolver의 역할: 
	컨트롤러 메서드의 매개변수에 맞는 값을 찾고, 이를 해당 타입으로 변환
    예를 들어, @RequestParam이나 @PathVariable로 요청 파라미터를 전달받는 것처럼, 
    ArgumentResolver는 파라미터에 적합한 값을 동적으로 설정
3.	컨트롤러 메서드 실행: 
	매개변수가 해결되면, Spring MVC는 이를 컨트롤러 메서드에 전달하고, 해당 메서드를 실행

3. 핸들러 메서드 인자 처리 방식

기본적으로 Spring은 여러 종류의 인자 변환을 지원하지만, 
특정 요구 사항에 맞는 사용자 정의 변환이 필요하다면 커스텀 ArgumentResolver를 구현하여 사용

* (참고)기본 ArgumentResolver

	•	@RequestParam: URL 쿼리 파라미터를 메서드 인자로 변환
	•	@PathVariable: URI 경로에서 변수를 추출하여 메서드 인자로 변환
	•	@RequestBody: HTTP 요청 본문을 객체로 변환 (예: JSON을 POJO로 변환)
	•	@ModelAttribute: 모델 객체를 생성하여 요청 데이터를 바인딩

4. 커스텀 ArgumentResolver 구현 예

@Component
public class CustomArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        // 특정 파라미터 타입에 대해서만 이 리졸버가 동작하도록 설정
        return parameter.getParameterType().equals(Long.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                  NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        // HTTP 요청에서 헤더 "X-User-Id"를 가져와 Long 타입으로 반환
        String userId = webRequest.getHeader("X-User-Id");
        return userId != null ? Long.parseLong(userId) : null;
    }
}

5. ArgumentResolver 등록

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Autowired
    private CustomArgumentResolver customArgumentResolver;

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(customArgumentResolver);  // 커스텀 ArgumentResolver 등록
    }
}

6. 사용 예시

@RestController
public class UserController {

    @GetMapping("/user")
    public String getUser(@RequestHeader("X-User-Id") Long userId) {
        return "User ID: " + userId;
    }
}

7. 장점과 활용

유연성: 
특정 데이터 변환 규칙에 맞게 요청 데이터를 처리할 수 있어 유연성이 높아짐

재사용성: 
복잡한 파라미터 변환 로직을 여러 컨트롤러에서 재사용 가능

가독성: 
코드의 가독성을 높이고, 중복을 줄이는 데 유리

 

 

참고 : 

더보기

* Interceptor와 ArgumentResolver의 차이
ArgumentResolver는 인터셉터 이후에 동작을 하며, 
어떠한 요청이 컨트롤러에 들어왔을 때, 
요청에 들어온 값으로부터 원하는 객체를 반환하기위해 사용한다. 
반면에 인터셉터는 실제 컨트롤러가 실행되기 전에 요청을 가로채며 특정 객체를 반환할 수 없고 
오직 boolean 혹은 void 반환 타입만 존재한다. 
하지만 파라미터로 받는 객체의 값을 변환하여 컨트롤러에 데이터를 전달할 수는 있다.
 
Request로부터 특정 객체를 추출하는 작업은 ArgumentResolver에서 수행하고
Interceptor는 인증/인가, 로깅 등의 본인만이 할 수 있는 작업을 진행하는 것이 가장 좋다

https://seongwon.dev/Spring-MVC/20220629-ArgumentResolver%EB%9E%80/

'Spring' 카테고리의 다른 글

CustomException  (0) 2025.02.07
필터와 인터셉터  (0) 2025.02.07
디버깅 모드  (1) 2025.01.19
FeignClient  (1) 2025.01.19
멀티 모듈 (Multi-Module)  (0) 2025.01.17