Spring MVC에서 커스텀 어노테이션을 사용하여 로그인된 사용자 정보를 자동으로 메서드 파라미터로 주입하는 방법을 소개합니다.
만약, 로그인을 진행한 후에 메인 페이지에 접속했을 때, 글을 작성하거나 검색하거나, 댓글을 작성할 때 등 많은 상황에서 로그인된 유저의 정보가 필요할 것입니다. 물론, 커스텀 어노테이션없이도 해당 로직을 쓸 수 있겠지만 훨씬 간편한 방법이 될 것 같아 포스트를 작성해봅니다.
전체적인 흐름을 먼저 설명하자면
- 사용자가 로그인하면, 로그인 정보를 세션에 저장합니다.
- @LoginUser 어노테이션을 Controller 메서드의 파라미터에 사용하면, Spring은 이 어노테이션을 처리할 ArgumentResolver를 통해 세션에서 사용자 정보를 가져옵니다.
- Controller에서 로그인된 사용자의 정보를 받아서 필요한 로직을 수행할 수 있습니다.
1. Custom Annotation (@LoginUser)
- 사용자가 로그인했는지 확인하고, 로그인된 사용자의 정보를 Controller 메서드 파라미터로 자동으로 주입하는 커스텀 어노테이션을 만든 것입니다.
- 이 어노테이션을 메서드 파라미터에 붙여 사용합니다.
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
}
2. Argument Resolver
- HandlerMethodArgumentResolver 인터페이스는 Spring MVC에서 메서드 파라미터를 동적으로 해결하는 방법을 제공합니다.
- @LoginUser 어노테이션을 처리할 ArgumentResolver를 작성하여, 로그인된 사용자 정보를 파라미터로 주입하도록 합니다.
- 이 Resolver는 Spring의 HandlerMethodArgumentResolver 인터페이스를 구현하고, 로그인된 사용자 정보를 세션에서 가져옵니다.
@RequiredArgsConstructor
@Component
public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver {
private final HttpSession session;
/* @LoginUser 어노테이션이 붙어 있고, 파라미터 클래스 타입이 UserDto.Response인가 판단 후 true반환 */
@Override
public boolean supportsParameter(MethodParameter parameter) {
boolean isLoginUserAnnotation = parameter.getParameterAnnotation(LoginUser.class) != null;
boolean isUserClass = UserDto.Response.class.equals(parameter.getParameterType());
return isLoginUserAnnotation && isUserClass;
}
/* 파라미터에 전달할 객체 생성 */
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return session.getAttribute("user");
}
}
3. WebMvcConfigurer
- Spring MVC의 설정을 확장할 수 있는 인터페이스입니다. 이 인터페이스를 구현하고 addArgumentResolvers() 메서드를 오버라이드하여 커스텀 ArgumentResolver를 Spring MVC에 등록합니다.
@RequiredArgsConstructor
@Configuration
public class WebConfig implements WebMvcConfigurer {
private final LoginUserArgumentResolver loginUserArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(loginUserArgumentResolver);
}
}
세션 관리:
- 로그인한 사용자의 정보를 HttpSession에 저장하여 애플리케이션의 다른 요청에서 사용하도록 합니다. 세션에 저장된 정보는 사용자가 로그인한 상태 동안 지속됩니다.
주입된 사용자 정보:
- 로그인된 사용자의 정보를 @LoginUser 어노테이션을 통해 자동으로 주입받아, Controller에서 이를 활용할 수 있습니다.
이 방식의 장점
- @LoginUser 어노테이션만 붙이면 자동으로 로그인된 사용자 정보를 주입받을 수 있어 코드가 간결하고 깔끔해집니다.
- 다양한 컨트롤러에서 로그인 정보를 쉽게 처리할 수 있습니다. 예를 들어, 여러 메서드에서 로그인된 사용자 정보를 사용해야 할 때마다 @LoginUser 어노테이션을 붙이기만 하면 됩니다.
- 분리된 책임: 로그인 처리와 사용자 정보 추출 로직을 분리하여 코드의 응집도를 높이고 유지보수가 용이해집니다.
이 개념은 AOP (Aspect Oriented Programming) 및 Interceptor 같은 기법과 유사한 방식으로, 사용자 인증/인가 관련 로직을 분리하여 처리하는 패턴입니다.
'Spring' 카테고리의 다른 글
그래서 OAuth 2.0로 로그인 어떻게 하는 건데 (0) | 2025.01.24 |
---|---|
@Valid 어노테이션으로 유효성 검사 (0) | 2025.01.19 |
Spring security Config 설정 | 생각없이 따라하다가 deprecated 놓치잖아 (0) | 2025.01.08 |
[Thymeleaf] 자꾸 챗지피티한테 맡기니까 뷰 짜는 머리가 퇴화하는데? (0) | 2024.12.27 |
[SpringMVC] Spring MVC 파헤치기 | 응답편 (2) | 2024.12.26 |