TroubleShooting] @Cacheable

JUNHYUK CHANG·2024년 3월 6일
1

TIL

목록 보기
26/33

1. @Cacheable을 붙여놓으면 캐시 히트 했을 땐 본문은 아예 실행 안된다.

@Cacheable 어노테이션이 적용된 메서드는 메서드가 호출될 때 캐시에서 데이터를 찾고, 데이터가 존재할 경우 메서드의 본문은 실행되지 않는다. 대신 캐시에서 찾은 데이터가 바로 반환된다.

이 동작은 캐시 히트가 발생했을 때 적용되며, 캐시에 저장된 데이터가 캐시의 키와 일치하는 경우에 해당된다. 만약 캐시에 저장된 데이터가 없거나 캐시 키와 일치하지 않는 경우에는 메서드의 본문이 실행되어 데이터를 생성하고, 이후에는 캐시에 저장된다.

2. @Cacheable이 붙은 메서드가 아무런 반환값이 없는 경우에는 캐시가 생성되지 않는다.

즉, 해당 메서드가 실행되어도 캐시에 저장되지 않는다. 메서드가 호출되어도 반환값이 없으므로 캐싱할 필요가 없다고 간주하기 때문이다.

3. 캐시 키 이름 규칙

@Cacheable 어노테이션에선 캐시의 이름과 키 를 설정할 수 있다.

@Cacheable(cacheNames = ["tickets"],
        key="#createTicketRequest.eventId + '_' " +
                "+ #createTicketRequest.date + '_' " +
                "+ #createTicketRequest.grade + '_' " +
                "+ #createTicketRequest.seatNo"
)

key 속성은 SpEL(Spring Expression Language)을 사용하여 정의된다.
Spring Expression Language(SpEL)은 스프링 프레임워크에서 사용되는 표현 언어로, 문자열 템플릿을 사용하여 다양한 기능을 제공하며, 주로 애노테이션, XML 설정 파일 등에서 사용된다.

'#' 기호를 사용하여 빈의 속성이나 메서드에 접근할 수 있다. 예를 들어, #user.name은 user 빈의 name 속성에 접근한다.

'${}' 기호를 사용하여 프로퍼티 값을 참조할 수 있다. 예를 들어, ${java.version}은 자바의 버전을 나타낸다.

이렇게 SpEL을 사용하여 동적으로 값을 지정하거나 조건에 따라 동작을 결정할 수 있기 때문에 코드의 유연성과 재사용성을 높일 수 있다.

4. @Cacheable self-invocation (in effect, a method within the target object calling another method of the target object). The cache annotation will be ignored at runtime

한 서비스 내의 메서드에서 @Cacheable이 적용된 다른 메서드를 호출하는 것은 권장되지 않는다. 이것은 "self-invocation"이라고도 불리며, Spring AOP에서 캐싱을 처리하는 데 문제가 발생할 수 있다고 한다.

@Cacheable이 적용된 메서드는 메서드 호출 시 AOP 프록시에 의해 런타임에 캐싱 로직이 적용되는데, 같은 빈 내에서 이러한 메서드를 호출하면 AOP 프록시를 우회하고 캐싱이 적용되지 않을 수 있다. 이는 예기치 않은 동작을 초래할 수 있으며, 캐시 무효화, 캐시 누수 및 동시성 문제 등을 초래할 수 있다.

대신, 같은 서비스 내에서 캐시가 필요한 로직은 메서드 밖에서 별도의 서비스나 컴포넌트로 분리하여 호출하는 것이 좋다. 이를 통해 캐시 로직이 제대로 동작하고 코드의 의도가 명확해지며, 예기치 않은 문제가 발생할 가능성을 줄일 수 있다.

예를 들어

createTicket() 에서 @Cacheable 어노테이션이 붙은 chkTicket() 메서드를 호출하면 어노테이션을 통해 값을 가져오는 대신 직접 본문을 실행하고 결과를 가져온다.

1개의 댓글

comment-user-thumbnail
2024년 3월 6일

뭔 내용인지 1도 모르겠습니다... -프론트엔드

답글 달기