트러블 슈팅 - AOP 순환 참조

Zyoon·2025년 6월 19일

트러블슈팅

목록 보기
5/11
post-thumbnail

❗AOP 적용 시 LogService에서 무한 루프 발생한 트러블슈팅


기존 코드

  • Spring AOP를 이용해 서비스 계층에서 발생하는 요청을 로그로 남기기 위해 포인트컷을 설정했다.
@Pointcut("execution(* com.example.outsourcing_project.domain..service..*(..))")
public void loggableServiceMethods() {}
  • 이 포인트컷은 com.example.outsourcing_project.domain 하위의 모든 service 패키지 내 메서드에 AOP를 적용하는 설정이다.

문제점

  • AOP의 핵심 로직인 saveActivityLog() 내부에서 logService.addLog()를 호출
  • 그런데 이 addLog()가 다시 AOP의 대상이 되어 saveActivityLog()가 또 실행됨
  • 그 안에서 다시 logService.addLog() → 또 AOP → 무한 반복
  • 결국 StackOverflowError 혹은 애플리케이션 정지

원인 분석

  • LogServiceaddLog() 메서드도 이 포인트컷에 포함되면서 무한 루프가 발생했다.
  • AOP는 프록시 기반으로 작동하므로, 프록시 메서드 내부에서 또다시 대상 메서드를 호출하면 AOP가 재귀적으로 실행된다.
  • 포인트컷에 LogService 자체가 포함되어 있었기 때문에 발생한 문제!

해결 방법

  • LogService는 로그를 기록하는 용도이기 때문에 AOP 대상에서 제외해야 합니다.

포인트컷 수정

@Pointcut("execution(* com.example.outsourcing_project.domain..service..*(..)) " +
    "&& !within(com.example.outsourcing_project.domain.log..*)")
public void loggableServiceMethods() {}
  • !within(...) 조건을 추가하여 Log 패키지 내의 모든 클래스를 AOP 적용 대상에서 제외
  • 결과적으로 logService.addLog()를 호출하더라도 AOP가 다시 적용되지 않음
  • 여러 서비스 클래스를 제외해야 할 경우 && !within(...) && !within(...) 식으로 연달아 쓸 수 있음
profile
기어 올라가는 백엔드 개발

0개의 댓글