@Inherited
// 메소드에서만 사용 가능
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AccessRole {
RoleFinal role();
}
@Aspect
@Component
public class AccessAspect {
private static Logger logger = LoggerFactory.getLogger(AccessAspect.class);
@AfterReturning(value = "execution(* com.dbkim.controller.*.*(..)) ||" +
"execution(* com.dbkim.exceptionHandler.ExceptionHandlers.nullEx(..))",
returning = "apiDTO")
public void loggerAfter(ApiDTO apiDTO) throws IOException {
if(apiDTO.getRtCode() != 0)
logger.error("HTTP/HTTPS Response : {}", apiDTO);
else
logger.info("HTTP/HTTPS Response : {}", apiDTO);
}
@Around("@annotation(com.dbkim.annotation.AccessRole)")
public Object accessRole(ProceedingJoinPoint joinPoint) throws Throwable {
...
return joinPoint.proceed();
}
AfterReturning에서 @annotation을 통해 타겟 메소드를 지정하는 것이 아닌,
execution로 지정하는 경우 해당 조건에 맞는 메소드들이 정상적인 리턴을 할 경우 AfterReturning 메소드가 실행됨따라서 어노테이션을 붙이지 않은 error 메소드에도 AfterReturning이 실행됨!!
(return값이 void가 아닌 AfterReturning의 returning 값과 같아야함!)
@PostMapping("/sign-up")
@ResponseBody
@AccessRole(role = RoleFinal.NONE)
public ApiDTO signUp(
@RequestBody UserRequest request
) throws Exception {
...
}
ProceedingJoinPoint의 getSignature 메소드를 활용하여
어노테이션을 통해 호출된 메소드를 가져온 뒤,
부여된 어노테이션의 고유한 값을 가져옴
@Around("@annotation(com.dbkim.annotation.AccessRole)")
public Object accessRole(ProceedingJoinPoint joinPoint) throws Throwable {
MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
RoleFinal role = methodSignature.getMethod().getAnnotation(AccessRole.class).role();