이번 장에서는 파라미터로 AOP를 구현하는 데에 스프링의 전략 인터페이스 중 하나인 HandlerMethodArgumentResolver에 대해서 알아보고자 한다.
전략 패턴의 일종으로 컨트롤러 메서드에서 특정 조건에 해당하는 파라미터가 있으면 생성한 로직을 처리한 후 해당 파라미터에 바인딩해주는 전략 인터페이스.
*전략 패턴 : 특정 전략을 인터페이스로 만들고 이를 여러 전략 객체로 구현한다. 그리고 현재 클래스 레벨에서 전략 인터페이스를 의존하도록 한다. 이런 식으로 느슨하게 연결된 전략 클래스를 찾아 의존하도록 하는 방식.
public interface HandlerMethodArgumentResolver {
boolean supportsParameter(MethodParameter parameter);
Object resolveArgument(MethodParameter parameter,
ModelAndViewContainer mavContainer, NativeWebRequest webRequest,
WebDataBinderFactory binderFactory) throws Exception;
}
@Target(ElementType.PARAMETER) //선언한 어노테이션이 적용될 수 있는 위치를 결정( 메서드 인자 )
@Retention(RetentionPolicy.RUNTIME) //어노테이션이 어느레벨까지 유지되는지 결정 ( 런타임에도 어노테이션이 제공되어 자바 reflection으로 선언한 어노테이션에 접근 )
public @interface SocialUser{
}
@Getter
@Setter
public class User{
private String name;
private Integer age;
private String address;
}
@RestController
public class TestController {
@GetMapping("/")
public Person test(@SocialUser User user){
return user;
}
}
@Component
public class CustomHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.getParameterType().equals(User.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
User user = new User();
user.setName("test");
user.setAge(21);
user.setAddress("seoul");
return user;
}
}
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private CustomHandlerMethodArgumentResolver customHandlerMethodArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(customHandlerMethodArgumentResolver);
}
}
서버를 키고 해당 localhost:8080에 접속하면
{"name":"test","age":21,"address":"seoul"}
와 같은 결과가 나온다.