Spring - AOP

송민지·2024년 9월 12일

AOP

Aspect Oriented Programming의 자로 관점 지향 프로그래밍입니다.
횡단관심사를 분리하여 개발하는 것을 말합니다.

횡단관심사?

횡단의 사전적 정의는 동서의 방향으로 가로지르는 것 입니다.
프로그래밍에서는 여러 부분에서 공통적으로 사용되는 기능입니다.
예시로는 트랜잭션, 로깅, 인증, 인가 등이 있습니다.

핵심기능

메서드의 주요 기능입니다. 회원가입의 경우 중복되는 id,닉네임이 있는지 확인 후 repository에 저장하는 기능입니다.

부가기능

핵심 기능이 아닌 부가적인 기능입니다. @Transactional등의 어노테이션이 있습니다.

횡단관심사

여러 곳에서 공통적으로 발생하는 부가기능입니다.

따라서

AOP는 핵심기능과 횡단관심사(부가기능)을 분리해서 관리, 개발하는 것을 말합니다.

AOP 키워드 정리

어드바이스(Advice)

실제로 실행되는 횡단관심사(부가기능) 코드입니다.
프로젝트 진행시 어드비아스는 로깅처리, 인증인가, 트랜잭션같은 부가기능으로 활용될 수 있습니다.

포인트컷(Pointcut)

어드바이스를 적용할 구체적인 범위를 선택하는 규칙입니다.
특정 패키지내의 메서드들이 대상이 될수도, 어노테이션으로 만들어 해당 컨트롤러에만 적용시킬수도 있습니다.

타겟(Target)

AOP에서 어드바이스가 적용되는 객체입니다. 특정 클래스가 타겟이되면, 그 클래스내의 모든 메서드들이 어드바이스의 적용을 받습니다.

조인포인트(Joinpoint)

어드바이스가 적용될 수 있는 실행 지점입니다. 메서드 기준으로 어드바이스가 동작하면, 메서드들이 조인포인트가 됩니다.

애스팩트(Aspect)

포인트컷, 어드바이를 하나로 묶은 모듈입니다.

개인과제로 보는 AOP


이 두 클래스는 Admin사용자만 접근이 가능합니다.

  • 요청한 사용자의 ID
  • API 요청 시각
  • API 요청 URL

이 포함된 AOP를 구현해야 합니다.

과제하는 도중 시행착오

 @Around("AdminLogsAnnotation()")
    public Object adminAnnotation(ProceedingJoinPoint joinPoint) throws Throwable {
        LocalDateTime startTime = LocalDateTime.now();

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            String userId = String.valueOf(request.getAttribute("userId"));
            log.info("userId ={} ", userId);
            String url = String.valueOf(request.getAttribute("requestURL"));
            log.info("url = {} ", url);
        }

        Object proceed = joinPoint.proceed();

        log.info("startTime = {}", String.valueOf(startTime));
        return proceed;
    }
  1. userId를 가져 올 수 없었던 이유는 application.properties파일을 작성하지 않아 DB에 저장할 수 없었기 때문입니다.
  2. DB연결 후 log를 확인해 봤지만 여전히 id, api요청시각, 요청url은 가지고 오지 못했습니다.
  3. filter에 저장된 유저 정보를 다음코드로 가져왔지만, 여전히 값은 들어오지 않았습니다.
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
httpRequest.setAttribute("userId", Long.parseLong(claims.getSubject()));
            httpRequest.setAttribute("email", claims.get("email"));
            httpRequest.setAttribute("userRole", claims.get("userRole"));
            httpRequest.setAttribute("requestURL", url);
  1. JwtFilter에 "httpRequest.setAttribute("requestURL", url);"
    을 추가하여 요구사항에 있는 userId, API 요청 시각, APIURL을 가져올 수 있었습니다.
profile
항상 밝게

0개의 댓글