🙋 @Cacheable 캐싱 안 먹는 이유? (Spring AOP)
Spring에서 @Cacheable 써서 캐싱할 때,
같은 클래스 안에서 메서드 부르면 AOP가 안 먹힌다. 그 이유는 Spring AOP는 프록시 객체로 동작하는데, 클래스 내부에서 자기 자신을 호출하면 프록시가 아니라 해당 메서드를 불러버리기 때문이다.
프록시는 외부에서 해당 메서드가 호출될 때만 동작한다.
@Service
public class userService {
public testResponse test(Long id) {
...
// user 정보 얻기
User user = getUser(id);
...
}
// 캐싱 적용
@Cacheable(value = "userCache", key = "#root.args[0]")
public User getUser(id){
return userRepository.findById(id)
}
}
✏️ 해결방법 첫번째, 서비스 분리
캐싱할 메서드를 다른 서비스(UserCacheService)로 빼버린다.
@Service
public class UserCacheService {
@Autowired
private UserRepository userRepository;
@Cacheable(value = "userCache", key = "#root.args[0]")
public User getUser(Long id){
return userRepository.findById(id);
}
}
✏️ 해결방법 두번째, 자기 자신을 빈으로 주입
서비스 나누기 싫다면? 자기 자신을 @Autowired을 통해 Bean으로 주입한다.
그러면 자기 자신 호출할 때도 프록시를 거치니까 AOP 적용되고 캐싱도 잘 된다.
@Service
public class UserService {
@Autowired
private UserService self; // 자기 자신을 주입
public TestResponse test(Long id) {
User user = self.getUser(id); // 프록시를 거쳐서 호출
}
@Cacheable(value = "userCache", key = "#root.args[0]")
public User getUser(Long id){
return userRepository.findById(id);
}
}
💡 Redis로 캐시 확인하는 방법
해당 프로젝트는 Redis를 캐시 저장소로 설정했다. (Redis는 Docker로 실행)
따라서 캐싱이 잘 적용됐는지 확인하기 위해 Redis CLI 사용.
Redis Docker 컨테이너 실행하고 Spring에서 Redis와 연동됐다는 가정하에,
1) Redis CLI 접속
Docker로 실행 중인 Redis에 접속하려면, 터미널에서 Redis CLI에 들어가서 명령어를 입력할 수 있다.
docker exec -it [redis 컨테이너 이름] redis-cli
2) 캐시된 키 확인
현재 Redis에 저장된 모든 캐시 키를 볼 수 있다.
keys *
'Spring' 카테고리의 다른 글
[JPA] Spring Data JPA - Entity에 기본 생성자가 필요한 이유? (0) | 2024.02.18 |
---|---|
[JPA] JPA 쿼리 생성 (쿼리 메소드, JPQL, QueryDSL) (1) | 2023.12.23 |
[Springboot, JPA] Springboot, JPA를 활용한 프로젝트 단계 - 참고 (0) | 2023.12.23 |
[Spring Boot] 동작 환경 - @ResponseBody, viewResolver (0) | 2023.09.15 |