티스토리 뷰

728x90
반응형

일반적으로 Cache는 CPU 내부에 위치한 저장소이며, 접근속도가 가장 빠릅니다. Spring에서 지원하는 캐시는 메소드를 동일한 파라밑로 반복적으로 호출하였을 때, 매번 메소드를 실행하지 않고, 과거에 실행한 메소드의 결과를 메소드 호출없이 데이터를 즉시 제공하는 것입니다. 메소드 코드를 실행하지 않고, 바로 응답결과를 얻을 수 있으면, 애플리케이션의 성능을 높일 수 있습니다. 이번 포스팅에서 Spring Framework에서 메소드에 캐시를 적용하는 방법에 대해 알아보겠습니다.

Cache의 정의

스프링에서 지원하는 캐시(Cache) 기능은 동일한 파라미터로 메서드를 호출하였을 때 이전에 호출된 결과 값을 메서드 실행 없이 그대로 반환하여 성능을 향상하는 메커니즘입니다.

Cache 활용

스프링 캐시는 언제 사용하는 게 좋을까요? 자바에서는 데이터를 인스턴스 단위로 다루기 때문에, 메서드 실행결과가 동일한 인스턴스를 반환한다면, 캐시를 적용하여 프로그램 수행 시간을 단축할 수 있습니다. 예를 들면, 데이터베이스로부터 조회한 결과 데이터가 매번 동일하다면, 조회 트랜잭션을 실행하지 않고 캐시에 저장된 데이터를 반환하면 실행 시간을 단축 가능합니다.

Cache 어노테이션 종류

스프링에서 캐시를 사용하는 방법은 캐시 기능을 사용하고자 하는 메서드에 어노테이션을 추가하면 됩니다. 캐시 어노테이션의 종류는 아래와 같습니다.

  • @Cacheable : 동일한 파리 미터로 메서드를 호출 이력과 반환 결과가 캐시에 저장되어 있으면, 캐시를 사용함
  • @CacheEvict : 캐시에 저장된 호출 이력 및 결과 값을 삭제함.
  • @CachePut : 캐시에 저장된 결괏값을 업데이트함.
  • @Caching : 여러 개의 캐시 어노테이션 옵션을 동시에 활성화하고자 할 때 사용. 
  • @CacheConfig : 캐시 옵션을 메서드 단위가 아닌 클래스 단위로 설정하고자 할 때 사용.

위의 어노테이션을 사용하기 위해서는 캐시 사용을 활성화하겠다는 @EnableCaching 어노테이션을 선언해야 합니다.

반응형
728x90

@Cacheable 사용법

캐시를 적용하고자 하는 메서드 위에 @Cacheable를 선언해줍니다. @Cacheable이 선언된 메서드는 메서드가 실행된 이력이 있으면, 이전에 반환했던 값을 그대로 반환합니다.

@Cacheable("books")
public Book getByIsbn(String isbn) {
    simulateSlowService();
    return new Book(isbn, "Some book");
}

simulateSlowService()는 테스트를 위해 3초간 Sleep 하는 메서드입니다. 예제에서는 Book 인스턴스가 반환되는데, 캐시가 적용되면 이전에 Book 인스턴스의 주소 값이 반환됩니다. 캐시가 올바르게 적용되었는지 메서드를 직접 호출하여 확인해보겠습니다. 

logger.info(".... Fetching books");
logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
bookRepository.getByIsbn("isbn-1234").setTitle("updated title");
logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));
logger.info("isbn-1234 -->" + bookRepository.getByIsbn("isbn-1234"));

위와 같이 메서드를 호출하여 메서드가 실행된 시간 간격을 확인해본 결과 캐시가 잘 적용된 것을 확인할 수 있습니다. 그리고 이전에 반환되었던 인스턴스가 동일하게 반환되는 것을 알 수 있습니다.

2022-06-02 15:07:06.868  INFO 3332 --- [           main] com.example.demo.AppRunner               : .... Fetching books
2022-06-02 15:07:09.906  INFO 3332 --- [           main] com.example.demo.AppRunner               : isbn-1234 -->Book{isbn='isbn-1234', title='Some book'}
2022-06-02 15:07:09.908  INFO 3332 --- [           main] com.example.demo.AppRunner               : isbn-1234 -->Book{isbn='isbn-1234', title='updated title'}
2022-06-02 15:07:09.909  INFO 3332 --- [           main] com.example.demo.AppRunner               : isbn-1234 -->Book{isbn='isbn-1234', title='updated title'}
2022-06-02 15:07:09.909  INFO 3332 --- [           main] com.example.demo.AppRunner               : isbn-1234 -->Book{isbn='isbn-1234', title='updated title'}

캐시가 저장될 저장소 이름을 cacheNames 속성으로 지정이 가능합니다. 캐시는 Key-Value로 데이터를 저장하므로, 사용자가 직접 Key를 지정 가능합니다.

@Cacheable(cacheNames="books", key="#isbn", cacheManager="anotherCacheManager")
public Book getByIsbn(String isbn, boolean checkWarehouse, boolean includeUsed)

Key를 지정하지 않았다면 KeyGenerator 알고리즘으로 Key 가 생성되는데, 생성하는 절차는 아래와 같습니다.

  • 메서드의 Parameter가 없는 경우, SimpleKey.EMPTY 값으로 Key가 지정됨
  • 메서드의 Parameter가 하나 이상인 경우, 파라미터 값을 기반으로 캐시의 Key가 생성됨

캐시 데이터를 조회하는 알고리즘을 사용자 정의로 구현하고 싶은 분은 cacheManager를 지정하여, CacheResolver를 구현할 수 있습니다.

728x90
반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함