같은 코드가 반복되는 부분을 어노테이션 기반으로 개선할 수 있음
IndexController에서 세션값 가져오는 부분을 메소드 인자로 세션값 바로 받을 수 있게 변경
@LoginUser 어노테이션 생성
package com.springAWS.config.auth;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginUser {
}
- Target(ElementType.PARAMETER)
- 이 어노테이션이 생성될 수 있는 위치 지정
- 메소드의 파라미터로 선언된 객체에서만 사용 가능
- 클래스 선언문에 쓸 수 있는 TYPE도 있음
- @interface
- 어노테이션 클래스로 지정
LoginUserArgumentResolver 클래스
HandlerMethodArgumentResolver 인터페이스 구현한 클래스
HandlerMethodArgumentResolver
- 조건에 맞는 경우 메소드가 있으면 이 구현체가 지정한 값으로 해당 메소드의 파라미터로 넘길 수 있음
package com.springAWS.config.auth;
import com.springAWS.config.auth.dto.SessionUser;
import lombok.RequiredArgsConstructor;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import javax.servlet.http.HttpSession;
@RequiredArgsConstructor
@Component
public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver {
private final HttpSession httpSession;
@Override
public boolean supportsParameter(MethodParameter parameter) { //컨트롤러 메서드의 특정 파라미터 지원하는지 판단
boolean isLoginUserAnnotation = parameter.getParameterAnnotation(LoginUser.class) != null;
boolean isUserClass = SessionUser.class.equals(parameter.getParameterType());
return isLoginUserAnnotation && isUserClass;
}
@Override //파라미터에 전달할 객체 생성, 여기서는 세션에서 객체 가져옴
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer
, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return httpSession.getAttribute("user");
}
}
- supportsParameter()
- 컨트롤러 메서드의 특정 파라미터 지원하는지 판단
- resolveArgument()
- 파라미터에 전달할 객체 생성
WebConfig 클래스
LoginUserArgumentResolver가 스프링에서 인식 가능하게 WebMvsConfigurer에 추가
package com.springAWS.config;
import com.springAWS.config.auth.LoginUserArgumentResolver;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
@RequiredArgsConstructor
@Configuration
public class WebConfig implements WebMvcConfigurer {
private final LoginUserArgumentResolver loginUserArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(loginUserArgumentResolver);
}
}
HandlerMethodArgumetResolver는 항상 WebMvcConfigurer의 addArgumentResolvers()로 추가해야함
IndexConroller에서 반복되는 부분 개선
@GetMapping("/")
public String index(Model model, @LoginUser SessionUser user) {
model.addAttribute("posts", postsService.findAllDesc());
if (user != null) {
model.addAttribute("userName", user.getName());
}
return "index";
}
어느 컨트롤러든지 @LoginUser만 사용하면 세션 정보 가져올 수 있음