기존에

스프링 AOP 주의사항 - 프록시 내부 호출, 초기화 에서 트랜잭션 관련 주의점을 AOP 관점에서 소개한 적이 있다. 이때 프록시 대상 내부에서 AOP를 호출하면 AOP가 제대로 안먹는걸 self-invocation이라고 한다.

스프링에서 @Cacheable 이라고 다를게 없다. 동일하게 프록시 기반 AOP를 이용하고 있기 때문에 이때도 이 점을 주의해야 한다.

@Transactional, @Async, @Cacehable 모두 해당된다.

정확한 동작은 다음과 같다.

  1. @EnableCaching 활성화
  2. 스프링이 “캐시 어드바이스(CacheInterceptor)”라는 AOP 어드바이스를 등록
  3. 캐시 어드바이스가 적용 가능한 bean(@Cacheable 메서드를 가진 bean)을 찾음
  4. 해당 bean을 AOP 프록시로 감싸서 컨테이너에 등록

메서드에 @Cacheable이 있는가? → 예

그럼 그 메서드를 가진 bean 전체를 프록시로 감싸서 등록.

따라서 이번에도 self-invocation문제가 발생할 수 있다.

가장 간단한 해결책은 두 클래스를 분리해버리는 것임.

자바를 이용할때 이너클래스를 만들거라면, 이너클래스를 static으로 만들어줘야 상위 클래스에 영향을 안받을 수 있다. 보통은 별도 파일로 아예 빼버리는게 간단하겠지만, 그냥 컨벤션때문에 한 파일에 만들어야 하고 코틀린이 아니라면 static nested inner class로 만드는게 방법임.