Spring

[SpringBoot] 커스텀 어노테이션 만들기

말랑말랑쓰 2021. 6. 17. 19:26

 

https://book.naver.com/bookdb/book_detail.nhn?bid=15871738

 

스프링 부트와 AWS로 혼자 구현하는 웹 서비스

가장 빠르고 쉽게 웹 서비스의 모든 과정을 경험한다.경험이 실력이 되는 순간!이 책은 제목 그대로 스프링 부트와 AWS로 웹 서비스를 구현합니다. JPA와 JUNIT 테스트, 그레이들, 머스테치, 스프링

book.naver.com

 

위 책을 보며 스프링부트 기반 JPA를 공부하고 있당

스프링을 처음 배우면서 가장 신기했고 흥미로웠던 것이 어노테이션인데(너무 편리함)

기 구현된 어노테이션을 사용만해봤지 커스텀으로 구현해본것이 처음이기때문에 까먹지 않기 위해 기록해본다!

커스텀 어노테이션을 만들 수 있을 것 같긴 했는데 생각 했던 것보다 구현 방법이 간단하다

왠지 두고두고 써먹을일이 많을것 같음ㅎㅎ

 

 


 

 

커스텀 어노테이션의 장점?

반복되는 코드를 줄일 수 있다. 자주 반복되고 여러 class에서 사용되는 코드가 있다면, 이를 어노테이션으로 구현함으로써 구현 코드가 간결해지고 개발자는 비즈니스 로직에 더욱 집중 할수 있다. 또한 관련 코드가 집중화 되어 있으니 수정에도 용이하다.

 

 

커스텀 어노테이션의 단점?

너무 당연한 이야기지만 뭐든 무분별하게 사용하면 안쓰는 것만 못하다. 무분별하게 사용되면 해당 어노테이션의 용도를 파악하기 위한 시간도 부가적으로 들 것이고, 그 수가 많다면 오히려 편리함보단 비효율적으로 작용할 것이다. 팀 프로젝트 개발의 경우 더더욱 커스텀 어노테이션의 장점을 살릴 수 있도록 적절한 어노테이션을 정의 해야 할듯하다.

 

 


구현 어노테이션

@LoginUser
  > HttpSession의 attribute 중 “user”이라는 이름으로 저장된 SesionUser 타입 객체를 가지는 파라미터 어노테이션
  > 로그인 상태 조회가 필요한 경우, 매번 HttpSession의 Attribute를 확인해서 가져오는 과정이 번거로움.
  > 이를 메소드 파라미터 어노테이션으로 제작하여 불필요한 코드를 제거하고 소스코드를 개선 

 

 

 

 

구현 구조

 

 

@interface LoginUser 
  • 정의하고자 하는 커스텀 어노테이션 클래스. 본문에서는 Login 정보를 HttpSession에서 가져오는 용도.
  • 필요 어노테이션
    • @Target(ElementType.PARAMETER)
      • @Target : 어노테이션이 정의 될 수 있는 위치를 설정하는 어노테이션
      • ElementType Enum : Parameter, Method, Field, Construct 등이 있으며 어노테이션 정의 위치를 의미
    • @Retention(RetentionPolicy.RUNTIME)
      • @Retention : 어노테이션의 유지 기간을 설정하는 어노테이션
      • RetentionPolicy Enum : Source, Class, Runtime이 있으며 어노테이션의 유지 기간을 설정하는 정책 종류
        • RetentionPolicy.Soruce :  컴파일러에 의해 삭제 됨. 
        • RetentionPolicy.Class : 컴파일 과정 이후 .class에 기록되지만, 런타임 시 VM에 유지되지 않음. (Default 타입)
        • RetentionPolicy.Runtime : .class에 기록되고 런타임 시 VM에서도 유지됨.

 

class LoginUserArgumentResolver
  • LoginUser 어노테이션을 사용하기 위한 설정을 수행하는 Resolver
  • 파라미터 어노테이션을 사용하기 위한 조건 설정, 값 설정 등을 수행하기 위하여 HandlerMethodArgumentResolver 인터페이스를 상속받음
  • 필요 어노테이션
    • @Component
  • 오버라이드 메소드
    • Return Type Method Name Parameter Comment
      boolean  supportsParameter MethodParameter parameter 해당 어노테이션을 지원할지 판단
      Object  resolveArgument MethodParameter parameter,
      ModelAndViewContainer mavContainer,
      NativeWebRequest webRequest,
      WebDataBinderFactory binderFactory
      파라미터에 전달할 객체 생성

 

 

class WebConfig
  • LoginUserArgumentHandler가 동작 되도록 등록하기 위한 Config
  • Resolver 등록을 위해 WebMvcConfigure 인터페이스를 상속받음
  • 필요 어노테이션
    • @Configure
  • 오버라이드 메소드
    • Return Type Method Name Parameter Comment
      void  addArgumentResolver List resolvers 인자로 받는 resolver list에  LoginUserArgumentResolver를 추가함

 

 


 

구현 방법을 정리하자면 

1. 커스텀 어노테이션 제작에 필요한 @Target, @Retention 어노테이션을 갖는 @interface 생성

(이때 @interface는 어노테이션이 아니라 하나의 타입임)

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

 

2. HandlerMethodArgumentResolver 인터페이스 상속 받는 Resolver 구현체 생성.

 

3. 새로 생성한 Resolver를 사용할수 있도록 Configure에서 설정.