2024-06-14 오늘의 TIL - AOP

이재성·2024년 6월 16일
post-thumbnail

AOP를 이용한 Controller

어노테이션

  • @Aspect : Spring 빈(Bean) 클래스에만 적용 가능
@Slf4j  //로그를 출력하기 위해서
@Aspect 
@Component  // 빈 클래스 선언을 하기 위해서
  • @Around: '핵심기능' 수행 전과 후 (@Before + @After)
  • @Before: '핵심기능' 호출 전 (ex. Client 의 입력값 Validation 수행)
  • @After: '핵심기능' 수행 성공/실패 여부와 상관없이 언제나 동작
    (try, catch 의 finally() 처럼 동작)
  • @AfterReturning: '핵심기능' 호출 성공 시 (함수의 Return 값 사용 가능)
  • @AfterThrowing: '핵심기능' 호출 실패 시.
    즉, 예외 (Exception) 가 발생한 경우만 동작 (ex. 예외가 발생했을 때 개발자에게 email 이나 SMS 보냄)

Pointcut

어드바이스가 실행되는 시기를 제어함
포인트컷 재사용 가능
포인트컷 결합 (combine) 가능

@Pointcut("execution(* com.sparta.areadevelopment.controller.*.*(..))")
 public void controller() {}

전체코드

@Slf4j
@Aspect
@Component
public class ControllerLogger {
    @Pointcut("execution(* com.sparta.areadevelopment.controller.*.*(..))")
    public void controller() {
    }
    @Around("controller()")
    public Object logging(ProceedingJoinPoint joinPoint) throws Throwable {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder
                .getRequestAttributes()).getRequest();

        String methodName = joinPoint.getSignature().getName();
        Map<String, Object> param = new HashMap<>();

        try{
            param.put("methodName", methodName);
            param.put("logTime", LocalDateTime.now());
            param.put("requestURL", request.getRequestURL());
            param.put("HTTP_METHOD", request.getMethod());
        }catch (Exception e){
            log.error("Error logging", e);
        }
        log.info("log info: {}", param);
        Object result = joinPoint.proceed();
        return result;
        }

}

AOP 적용 후 생긴 에러

에러 내용을 보니 commentController 하나만 콕 찝어서 에러가 났다고 알려주고 있었다.
왜 이런 내용을 보냈는지 몰라서 다른 controller들과 비교를 해보니
다른 controller들은 @RequiredArgsConstructor를 사용하였다. 하지만 다른 하나는
사용하지 않고 생성자 주입을 하였는데 에러가 나지 않은 것이다..

둘의 차이가 뭘까?? 했더니 commentController는 생성자 주입을 private로 생성을 한 것 밖에 차이가 없었다.

왜 이 차이가 에러를 만드는가

spring2.5이후 부터는 default로 CGLIB을 사용하는데 상속을 통해 프록시를 구현한다
상속은 private를 상속할 수없다...
즉, public이외의 메서드는 AOP가 걸리지 않는다.

해결 후 실행

profile
하이요

0개의 댓글