https://docs.spring.io/spring-framework/reference/integration/cache/strategies.html
https://docs.spring.io/spring-framework/reference/integration/cache/annotations.html
우테캠 쇼핑 미션 5단계인 외부 API 호출을 어떻게 처리할지 고민하다가 캐싱 적용을 고려하게 되었다. 다음은 스프링에서 캐싱을 어떻게 처리하는지 공식 문서를 읽고 필요한 부분만 정리한 내용이다.
버퍼와 캐시는 모두 속도가 빠른 장치와 느린 장치 간의 처리 속도 차이로 인한 비효율을 완화하는 임시적인 저장소이다. 그렇다면 어떤 점이 다른가?
스프링의 캐시 추상화는 메서드 단위로 적용된다. 메서드가 호출된 적이 있으면 캐시된 데이터가 반환되고 실제 호출은 이루어지지 않는다. 메서드가 호출된 적이 없으면 메서드가 호출되고 반환값이 캐시된다. 이 값은 나중에 재사용된다.
이를 통해 같은 파라미터로 메서드를 다시 호출하는 경우 이전의 결과를 재사용할 수 있다. CPU나 IO 자원을 많이 이용하는(추가적으로, 같은 인자에 대해 같은 결과를 반환하는) 메서드의 경우 캐싱을 이용하면 좋을 것이다.
스프링은 캐싱 로직에 대한 추상화만 제공하고 실제로 데이터를 저장할 저장소를 필요로 하는데 이는 Cache, CacheManager 인터페이스로 구체화된다. 스프링은 ConcurrentHashMap, Gemfire, Caffine 등 몇 가지 구현체를 제공한다.
캐시 추상화를 사용하기 위해 두 가지 측면을 고려해야 한다.
value 필드에는 메서드와 연관되는 캐시 이름을 지정한다.@Cacheable("books")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
KeyGenerator는 다음과 같이 키를 생성한다.SimpleKey.EMPTY를 반환SimpleKey 객체를 반환equals, hashcode를 구현해야 함KeyGenerator를 사용하고 싶다면 해당 인터페이스를 구현하면 된다.SpEL(Spring Expression Language)를 사용할 수 있다.@Cacheable(cacheNames="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
@Cacheable(cacheNames="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
@Cacheable(cacheNames="books", key="T(someType).hash(#isbn)")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
cacheManager 필드에 사용할 CacheManager를 지정할 수 있다.sync 필드를 true로 설정할 수 있다. 이를 사용하면 한 스레드가 값을 계산 중일 때 다른 스레드들을 블록할 수 있다.condition 필드와 unless 필드를 사용하면 조건적인 캐싱이 가능하다.@CachePut과 @Cachable을 함께 사용하면 안 된다. 예상하지 못한 동작을 유발할 수 있다.allEntries 필드를 true로 지정하면 캐시 데이터가 전부 삭제된다. 이때는 키를 지정해도 무시된다.beforeInvocation 필드를 true로 지정하면 메서드가 실행되기 전에 eviction이 일어난다.@Cacheable과 다르게 메서드 반환 타입이 void여도 상관없다.@Caching(evict = { @CacheEvict("primary"), @CacheEvict(cacheNames="secondary", key="#p0") })
public Book importBooks(String deposit, Date date)
@CacheConfig("books")
public class BookRepositoryImpl implements BookRepository {
@Cacheable
public Book findBook(ISBN isbn) {...}
}
유익한 글이었습니다.