HandlerMethodArgumentResolver

이동훈·2023년 8월 10일
0

@interface

아쉽게도,

public @interface MyCustomArgumentResolver implements HandlerMethodArgumentResolver

위와 같은 방식으로는 (당연하지만) 사용이 불가능하다.

내장 어노테이션과 달리 커스텀 어노테이션 자체에 어떠한 기능을 넣는건 불가능하다는 소리.

코드

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCustomAuthorization {
    String value() default "";
}
💡 @Target은 이 어노테이션이 적용될 대상의 종류를 지정하는 데에 쓰인다.
  1. ElementType.ANNOTATION_TYPE: 다른 어노테이션을 정의할 때 사용하는 어노테이션.
  2. ElementType.CONSTRUCTOR: 생성자에 어노테이션을 적용할 수 있음.
  3. ElementType.FIELD: 필드(멤버 변수)에 어노테이션을 적용할 수 있음.
  4. ElementType.LOCAL_VARIABLE: 지역 변수에 어노테이션을 적용할 수 있음.
  5. ElementType.METHOD: 메서드에 어노테이션을 적용할 수 있음.
  6. ElementType.PACKAGE: 패키지에 어노테이션을 적용할 수 있음.
  7. ElementType.PARAMETER: 메서드의 매개변수에 어노테이션을 적용할 수 있음.
  8. ElementType.TYPE: 클래스, 인터페이스, 열거형 등의 타입에 어노테이션을 적용할 수 있음.

클래스에 붙을 어노테이션(e.g. @Controller)은 ElementType.TYPE,
메소드에 붙을 어노테이션(e.g. @RequestMapping)은 ElementType.METHOD,
파라미터에 붙을 어노테이션(e.g. @RequestParam)은 ElementType.PARAMETER

이런 식이 되겠다.

💡 @Retention은 어노테이션의 생명 주기를 지정하는 것.
  1. RetentionPolicy.SOURCE: 컴파일 시간까지만 어노테이션 정보를 유지하며, 클래스 파일에는 포함되지 않는다. 따라서 런타임 환경에서 어노테이션 정보를 확인할 수 없다.
  2. RetentionPolicy.CLASS: 컴파일 시간까지 어노테이션 정보를 유지하며, 클래스 파일에는 포함되지만 런타임 환경에서 어노테이션 정보를 확인할 수 없다. 일반적으로 기본 값이며, 런타임에 어노테이션을 사용할 필요가 없는 경우에 이 옵션을 사용.
  3. RetentionPolicy.RUNTIME: 컴파일 이후에도 어노테이션 정보를 유지하며, 런타임 환경에서 어노테이션 정보를 확인할 수 있다. 이 옵션을 사용하면 런타임에 어노테이션의 속성을 리플렉션을 통해 조회하거나 처리할 수 있다.

HandlerMethodArgumentResolver (implements)

이전 포스팅(링크)에서 소개한 WebArgumentResolver의 개선 버전 interface이다.

Declaration된 메소드에 supportsParameter가 추가되었으며,

원하는 대상이 맞는지 확인하여, 이에 true를 받을 시 resolveArgument로 넘어갈 수 있다.

코드

public class MyCustomArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(MyCustomAuthorization.class);
    }

    @Override
    public Object resolveArgument(
            MethodParameter parameter,
            ModelAndViewContainer mavContainer,
            NativeWebRequest webRequest,
            WebDataBinderFactory binderFactory
    ) throws Exception {
        // @MyCustomAuthorization 어노테이션이 적용된 매개변수를 처리하는 로직 작성
        // 예를 들어, 스프링 시큐리티의 사용자 권한 체크 등을 수행.
        String requiredAuthority = parameter.getParameterAnnotation(MyCustomAuthorization.class).value();
        
        // 문자열로 반환 예
        return requiredAuthority;
    }
}

용례

파라미터에 사용되었다는 예시로 설명하면,

// 컨트롤러 클래스
@Controller
public class MyController {

    @RequestMapping("/example")
    public String exampleMethod(@MyCustomAnnotation("ROLE_ADMIN") String role) {
        // 컨트롤러 로직
        return "result";
    }
}

위와 같은 방식으로, role이 ROLE_ADMIN이면 resolver의 supportParameter에서 true를 받아, resolveArgument 메소드의 처리를 받을 수 있다.

아무 값도 넣지 않고 어노테이션만 호출한다면, (예시- @MyCustomAnnotaion String role)

@interface에서 선언했던 default값이 호출될 것이다.

default값을 설정하지 않으면 속성값 미지정 시 컴파일 에러가 발생하므로 설정을 해주도록 하자.

profile
Fool Snack Developer

1개의 댓글

comment-user-thumbnail
2023년 8월 10일

잘 봤습니다. 좋은 글 감사합니다.

답글 달기