본문 바로가기

커스텀 파라미터, 그 원리와 사용방법은?

커스텀 파라미터 구현

설명에 앞서, 먼저 간단한 예시 코드를 작성해본다.

다음과 같은 커스텀 파라미터를 가정한다.

@Target(ElementType.PARAMETER)  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
public @interface CurrentUserId {  
}  
@CurrentUserId 자체는 파라미터 전용 런타임 Annotation입니다.  

이는 다음 커스텀 Resolver가 처리한다.

Resolver에 필요한 supportsParameter와 resolveArgument를 Override해주었다.

public class CurrentUserIdArgumentResolver implements HandlerMethodArgumentResolver {  

@Override  
public boolean supportsParameter(MethodParameter parameter) {  
  return parameter.hasParameterAnnotation(CurrentUserId.class)   
    && Long.class.equals(parameter.getParameterType());  
}  

@Override  
public Long resolveArgument(...머시깽이...) {  
  ...저시깽이...  
}

마지막으로 설정을 위해 WebConfig에 다음을 추가했다고 가정한다.

Resolver 목록에 방금 제작한 커스텀 Resolver를 추가한 것이다.

이로써 방금 생성한 어노테이션을 활용할 수 있다.

@Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {   
  resolvers.add(new CurrentUserIdArgumentResolver());   
}

커스텀 파라미터는 어떻게 인식되는가?

이제 컨트롤러에서 다음으로 호출하는 경우를 보자.

Controller의 파라미터부터

@PostMapping("/api/participate")  
ApiResponse<?> participate(@CurrentUserId Long userId)

Spring MVC는 컨트롤러 호출 직전에 각 파라미터를 하나씩 해석한다.

@CurrentUserId Long userId를 만나면
resolver 목록을 돌면서 supportsParameter()를 호출하고,
현재 resolver가 true를 반환한다.
그 다음 resolveArgument()가 실행된다.

resolver 흐름

상기 예시의 HandlerMethodArgumentResolver를 다시 보자.

public class CurrentUserIdArgumentResolver implements HandlerMethodArgumentResolver {

@Override  
public boolean supportsParameter(MethodParameter parameter) {  
  return parameter.hasParameterAnnotation(CurrentUserId.class)   
    && Long.class.equals(parameter.getParameterType());  
}  

@Override  
public Long resolveArgument(...머시깽이...) {  
  ...저시깽이...  
}  

이 Resolver는 @CurrentUserId에 대하여,
supportsParameter에 의해 true를 반환한다.

이후, resolveArgument()는 "저시깽이"의 코드에 따라 Long 값을 반환한다.

그리고 이 Long 값이 아까 봤던 Controller의 다음 코드에서
@CurrentUserId Long userId 내부에 들어갈 값이다.

@PostMapping("/api/participate")  
ApiResponse<?> participate(@CurrentUserId Long userId)
NORMAL j/k: 이동 · Enter: 열기 · /: 검색 · ?: 도움말