ArgumentResolver
로 동작하는 어노테이션@RequestParam
: 쿼리 파라미터 값 바인딩@ModelAttribute
: 쿼리 파라미터 폼 및 데이터 바인딩@CookieValue
: 쿠키값 바인딩@RequestHeader
: 헤더값 바인딩@RequestBody
: 바디값 바인딩ArgumentResolver
로 구현하였다.@PostMapping("/sign-up")
public ResponseEntity<HttpStatus> register(@RequestBody MemberSignUpRequest memberSignUpRequest,
@LoginMember Member member) {
memberService.register(member, memberSignUpRequest);
return ResponseEntity.status(HttpStatus.OK).build();
}
MemberController
에 구현되어 있는 회원가입에 대한 코드이다.register()
의 매개변수를 보면 @LoginMember Member member
를 볼 수 있을 것이다.@LoginMember
의 역할은 헤더를 통해서 넘어온 JWT에서 사용자 정보를 가져와 Member member
에 주입시켜주는 역할이다.memberService.getLoginMember
@Transactional(readOnly = true)
public Member getLoginMember() {
String accessToken = jwtService.extractAccessToken(request).orElseThrow(NotFoundTokenException::new);
String email = jwtService.extractEmail(accessToken).orElseThrow(NotFoundEmailException::new);
Member member = memberRepository.findByEmail(email).orElseThrow(NotFoundMemberException::new);
return member;
}
만약
Resolver
를 구현하지 않았다면Controller
에서 인증된 사용자 객체가 필요할 때마다, 위 메서드를 불러와야한다.
하지만Resolver
를 구현함으로써, 반복되는 코드를 적는 것이 아닌@LoginMember
를 통해서 인증된 사용자 객체를 주입받을 수 있게 되었다.
@LoginMember
Controller
에서 인증된 사용자 객체를 주입해주는 어노테이션.import java.lang.annotation.Documented;
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)
@Documented
public @interface LoginMember {
}
@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
LoginMemberArgumentResolver
Controller
에서 @LoginMember
이 적용된 Member
에 인증된 사용자 객체를 주입해주는 코드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 com.example.memetory.domain.member.service.MemberService;
import com.example.memetory.global.annotation.LoginMember;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@RequiredArgsConstructor
@Component
public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {
private final MemberService memberService;
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
return methodParameter.hasParameterAnnotation(LoginMember.class);
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer,
NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) {
return memberService.getLoginMember();
}
}
HandlerMethoadArgumentResolver
는 컨트롤러 메서드의 매개변수를 해석하고 해당 매개변수에 값을 제공한다.boolean supportsParameter()
@LoginMember
가 있는지 확인해주는 메서드이다.Object resolveArgument()
@LoginMember
가 적용된 변수에 인증된 사용자 객체(Member
)를 주입해주는 Resolver
의 메인 로직이다.resolverArgument()
의 매개변수MethodParameter methodParameter
ModelAndViewContainer modelAndViewContainer
NativeWebRequest nativeWebRequest
WebDataBinderFactory webDataBinderFactory
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import com.example.memetory.global.resolver.LoginMemberArgumentResolver;
import lombok.RequiredArgsConstructor;
@Configuration
@RequiredArgsConstructor
public class WebConfig implements WebMvcConfigurer {
private final LoginMemberArgumentResolver loginMemberArgumentResolver;
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(loginMemberArgumentResolver);
}
}
WebMvcConfigurer
addArgumentResolvers()
HandlerMethoadArgumentResolver
를 등록하는 역할을 한다.