ArgumentResolver 구현

정병웅·2025년 1월 12일
0

back-end

목록 보기
3/6

토이 프로젝트를 진행 중에 로그인 프로세스에 AgumentResolver를 적용해보았던걸 정리해본다 하지만,,,아직도 100프로 이해를 하지는 못했고 왜 사용하는지 정도만 느끼게 됐다,,,(멀고도 힘든 스프링의 세계😔)

ArgumentResolver 사용 이유

컨트롤러 메서드의 파라미터를 이용하여 로직 구현 시 여러 컨트롤러에 중복 되는 로직이 있을 경우 중복 로직을 줄이기 위해서 사용하는게 가장 큰 이유로 느껴진다.

구현 방법

1. 어노테이션 생성

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Login {
}

코드 설명
@Target : 어노테이션이 파라미터의 타입에만 적용 된다는 설정의 어노테이션
@Retention : 어노테이션이 런타임에도 유지 되어, reflection 통해 사용 할 수 있다는 어노테이션

  • reflection 이란?
    - 자바 프로그램이 실행 되는 동안(런타임)에 객체에 접근 할 수 있다.
    1. 클래스 정보 조회
      • 클래스의 이름, 패키지, 접근 제어자(public, private 등) 등 정보를 알아낼 수 있음.
      • 클래스의 멤버(필드, 메서드, 생성자 등)를 동적으로 값을 가져옴.

2. HandlerMethodArgumentResolver 구현 클래스 생성

/** 로그인 멤버 객체 바인딩 Resolver */
@Slf4j
public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        // Login 어노테이션이 붙어있다면 true
        boolean hasLoginAnnotation = parameter.hasParameterAnnotation(Login.class);
        // Member 타입일 경우 true
        boolean hasMemberType = Member.class.isAssignableFrom(parameter.getParameterType());
        return hasLoginAnnotation && hasMemberType;
    }

    /* 서비스 로직 처리 */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest();
        // 요청에 세션 get
        HttpSession session = request.getSession(false);
        if (session == null) {
            return null;
        }
        // 세션에 로그인 멤버 값 있을 경우 Member 타입 객체 return
        return session.getAttribute(SessionConstant.SESSION_KEY);
    }
}

코드 설명
supportsParameter 메서드

  • Login 어노테이션이 붙어 있는지 체크
  • Login 어노테이션이 붙어있는 파라미터 타입이 바인딩 대상 클래스와 동일한지 타입 체크

resolveArgument 메서드

  • supportsParameter 메서드가 true 일 경우 실행 됨.
  • 실제 구현해야할 로직 처리를 작성

3. WebMvcConfigurer 구현 클래스에 addArgumentResolvers 메서드 생성

@Configuration
public class Config implements WebMvcConfigurer {
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(new LoginMemberArgumentResolver());
    }
}

코드 설명
생성한 ArgumentResolver를 WebMvcConfigurer를 구현한 클래스 내부에 정의 한다.

  • addArgumentResolvers에서 생성한 LoginMemberArgumentResolver를 추가

4. argumentResolver를 사용할 컨트롤러에 구현

/* 홈화면 접근 */
    @GetMapping("/")
    public String home(@Login Member loginMember, Model model) {
        // 세션에 회원 데이터 없으면 home 으로 이동
        if (loginMember == null) {
            return "home";
        }
        // 세션에 로그인 정보가 있을 경우 로그인 된 페이지 호출
        model.addAttribute("loginUserVo", loginMember);
        return "loginMain";

    }

코드 설명
@Login 어노테이션이 붙은 Member 타입의 loginMember 파라미터를 ArgumentResolver를 수행 후 return 값에 따라 로그인 정보 처리 수행

ArgumentResolver 처리 과정

  1. 클라이언트의 요청
  2. Dispatcher Servlet으로 요청 인입 후 처리
  3. 인터셉터가 있을 경우 인터셉터 먼저 처리
  4. ArgumentResolver 처리
  5. 컨트롤러 메서드 호출 후 요청 실

  • 로그 콘솔에서 확인 하면 알 수 있듯이 Dispatcher Servlet으로 요청이 인입 된 후에 인터셉터가 실행 되고, ArgumentResolver 가 실행 되는 것을 알 수 있다!
profile
인생은 IT 노가다

0개의 댓글