커스텀 어노테이션으로 로그인 사용자 정보 받아오기 (@LoginUser)

김현정·2025년 4월 14일
0
@Component
public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private UserService userService;

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        // @LoginUser 어노테이션이 붙은 파라미터만 처리하도록 설정
        return parameter.hasParameterAnnotation(LoginUser.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        // 세션에서 로그인된 사용자 정보 가져오기
        ServletWebRequest servletWebRequest = (ServletWebRequest) webRequest;
        HttpServletRequest request = servletWebRequest.getRequest();
        HttpSession session = request.getSession(false);

        if (session == null || session.getAttribute("userId") == null) {
            throw new RuntimeException("로그인 해주세요.");
        }

        Long userId = (Long) session.getAttribute("userId");

        // UserService를 사용하여 DB에서 사용자 정보 조회
        User user = userService.findById(userId);

        return user; // 로그인된 사용자 객체를 반환
    }

}

Spring MVC 프로젝트를 하다 보면 로그인한 사용자 정보를 컨트롤러에서 자주 받아와야 할 때가 많습니다.
HttpSession에서 직접 값을 꺼내 쓰는 방식도 있지만, 매번 반복해서 쓰기보다는 깔끔하게 커스텀 어노테이션을 만들어 자동으로 처리되게 할 수 있습니다.

이번 글에서는 @LoginUser라는 커스텀 어노테이션을 만들어 로그인된 사용자 정보를 컨트롤러 메서드 파라미터에 자동 주입하는 방법을 소개합니다.

구조 : 요청 → DispatcherServlet → ArgumentResolver(@LoginUser) → 세션에서 userId 꺼냄 → DB 조회 → User 객체 반환

어노테이션 생성

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

Spring MVC에서 컨트롤러 메서드에 로그인된 사용자 정보를 자동으로 주입하기 위한 커스텀 Argument Resolver

  1. @Component : 스프링이 자동으로 이 클래스를 빈으로 등록하게 해줌.

  2. HandlerMethodArgumentResolver 인터페이스 : 컨트롤러 메서드에서 특정 조건에 맞는 파라미터가 있을 때 원하는 값을 바인딩해주는 인터페이스
    -> 컨트롤러 메서드의 파라미터에 값을 넣어주는 로직을 우리가 직접 정의할 수 있도록 해주는 확장 포인트
    -> 이걸 활용해서 @LoginUser 어노테이션이 붙은 파라미터에 로그인된 사용자 정보를 자동 주입하게 만듬

  3. @Autowired : 필요한 의존 객체의 "타입"에 해당하는 빈을 찾아 주입.

  4. @LoginUser 어노테이션 붙은 파라미터에만 설정

@Override
    public boolean supportsParameter(MethodParameter parameter) {
        // @LoginUser 어노테이션이 붙은 파라미터만 처리하도록 설정
        return parameter.hasParameterAnnotation(LoginUser.class);
    }
  1. webRequest는 NativeWebRequest타입인데 웹 요청을 추상화한 객체, ServletWebRequest로 다운캐스팅 한 것.

  2. request.getSession(false)은 세션이 있으면 가져오고, 없으면 null을 리턴
    (true를 넣으면 세션이 없으면 새로 생성해버림, false는 세션이 있을 때만 가져오도록 제한)

// 1. Spring 추상화된 요청(webRequest)을 실제 ServletRequest로 다운캐스팅
ServletWebRequest servletWebRequest = (ServletWebRequest) webRequest;

// 2. 진짜 HttpServletRequest 꺼냄
HttpServletRequest request = servletWebRequest.getRequest();

// 3. 세션이 있으면 가져옴 (없으면 null)
HttpSession session = request.getSession(false);

// 4. 세션이 없다면 예외 처리
if (session == null) {
    throw new RuntimeException("로그인 해주세요.");
}

0개의 댓글