java spring - Custom annotation을 만들어보자

Annotation 이란 ?

소스코드에 제공되는 메타데이터이다. 앱이 처리하는 데이터가 아닌 컴파일 과정,실행 과정에서 코드를 어떻게 처리해야 하는지 알려주는 용도로 사용된다.
ex ) @Controller @Service

# 직접 만들어 보자.

이러한 어노테이션을 사용자가 직접 정의 하여 구현 할 수도 있다.

# 시나리오

특정 권한을 체크하는 커스텀 어노테이션을 만들어 적용해보자.

// 커스텀 어노테이션 선언
@Retention(RetentionPolicy.RUNTIME) // 2
@Target({ElementType.TYPE, ElementType.METHOD}) // 3
public @interface CheckRole { // 1
    Authority auth();
}
------------------------------------------------------------
// 권한 클래스
@AllArgsConstructor
@Getter
public enum Authority {
    ADMIN("ROLE_ADMIN"),
    USER("ROLE_USER");

    private String value;

}
  1. @interface 로 커스텀 어노테이션 임을 명시해준다.
  2. @Retention - 해당 어노테이션의 유효성을 나타낸다.
  3. @Target - 해당 어노테이션의 사용 가능한 위치를 나타낸다.

# AOP

@Aspect
@Component
@RequiredArgsConstructor
public class CheckRoleAop {

    private final MemberRepository memberRepository;
    private final JwtTokenProvider tokenProvider;

	// 1
    @Pointcut("execution(* com.kjw.shop..*.*(..))")
    private void cut(){}
    
	// 2
    @Before("cut() && @annotation(auth)")
    public void before(JoinPoint joinPoint,CheckRole auth) {
		// 3
		HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
        String header = request.getHeader("X-AUTH-TOKEN");
        Member member = memberRepository.findById(tokenProvider.getUserPk(header))
                .orElseThrow(() -> new IllegalArgumentException("error"));
		// 4
        String checkRole = auth.auth().getValue();
        String memberRole = member.getRoles().get(0).getName().getValue();

        System.out.println("checkRole = " + checkRole);
        System.out.println("memberRole = " + memberRole);

    }
}

방금 만든 어노테이션이 붙은 메서드가 실행되기 전 동작하는 AOP 이다.
1. 어떤 JoinPoint 에서 사용 될 것인지 명시해준다.
2. @Before 은 해당 괄호 조건이 실행되기 전에 작동한다. 여기서는 com.kjw.shop 하위 패키지이면서 @CheckRole 커스텀어노테이션 auth가 있는 곳이다.
3. 헤더에있는 토큰으로 사용자 정보를 불러오는 곳.
4. 실제 커스텀 어노테이션에서 제한한 권한과 사용자의 권한 비교

# 적용

@RestController
@RequestMapping(value = "/admin")
public class HomeController {

    @GetMapping("/test")
    @CheckRole(auth = Authority.ADMIN)
    public String test() {
        return "hello";
    }
}

# 결과

커스텀 어노테이션을 만들어 권한이 다르면 예외를 던지거나 로그를 찍을수도있다.
사용자 입맛에 맞게 구현하면 된다.

좋은 웹페이지 즐겨찾기