轻松使用Spring的缓存功能
这是一个使用Spring(Spring Boot)的缓存功能来缓存方法调用结果的示例。
确认动作版本
- 
- Spring Boot 2.7.5
 
 
- Spring Framework 5.3.23
 
启用缓存功能
当使用 @EnableCaching 注解后,Spring Boot 的自动配置功能会使得可以使用 Spring 的缓存功能。
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching // ★★★アノテーションを追加
public class SpringCacheDemoApplication {
  public static void main(String[] args) {
    SpringApplication.run(SpringCacheDemoApplication.class, args);
  }
}
指定缓存目标方法
給希望將結果快取的方法加上@Cacheable標記。在以下示例中,我們將緩存名稱設定為「rates」。
package com.example.demo;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.security.SecureRandom;
import java.util.UUID;
@Component
public class RateRepository {
  @Cacheable("rates") // ★★★ キャッシュしたいメソッドにアノテーションを追加
  public Rate getRate(String unitId, String groupId, String type, String baseDate) {
    Rate rate = new Rate();
    rate.setId(UUID.randomUUID().toString());
    rate.setRate(BigDecimal.valueOf(new SecureRandom().nextLong()));
    return rate;
  }
}
试着动一下
当运行以下JUnit时,可以发现在以相同参数调用方法的情况下,将返回缓存的实例。
@SpringBootTest
class SpringCacheDemoApplicationTests {
  @Autowired
  RateRepository rateRepository;
  @Test
  void contextLoads() {
    Rate rate1 = rateRepository.getRate("U001", "G001", "Credit", "20221114");
    Rate rate2 = rateRepository.getRate("U001", "G001", "Credit", "20221114");
    // ★★★ 同じインスタンスが返却される
    Assertions.assertThat(rate2.getId()).isEqualTo(rate1.getId());
    Assertions.assertThat(rate2.getRate()).isEqualTo(rate1.getRate());
    Assertions.assertThat(rate2).isSameAs(rate1);
  }
}
在测试类中删除缓存
为了确保测试不会影响其他测试,我们最好在每次测试之前清除已缓存的数据。因此,在测试类中注入CacheManager来清除缓存。
@SpringBootTest
class SpringCacheDemoApplicationTests {
  @Autowired
  RateRepository rateRepository;
  @Autowired
  CacheManager cacheManager;
  // ★★★ テスト実施前後にキャッシュをクリアする
  @BeforeEach
  @AfterEach
  void clearCache() {
    cacheManager.getCacheNames().stream()
        .map(cacheManager::getCache)
        .filter(Objects::nonNull)
        .forEach(Cache::clear);
  }
  @Test
  void contextLoads() {
    Rate rate1 = rateRepository.getRate("U001", "G001", "Credit", "20221114");
    Rate rate2 = rateRepository.getRate("U001", "G001", "Credit", "20221114");
    Assertions.assertThat(rate2.getId()).isEqualTo(rate1.getId());
    Assertions.assertThat(rate2.getRate()).isEqualTo(rate1.getRate());
    Assertions.assertThat(rate2).isSameAs(rate1);
    // ★★★ 明示的にキャッシュを削除してみる
    clearCache();
    // ★★★ キャッシュ削除後に同じパラメータでメソッドを呼び出しみる
    Rate rate3 = rateRepository.getRate("U001", "G001", "Credit", "20221114");
    // ★★★ Cacheクリア後は別のインスタンスが返却される
    Assertions.assertThat(rate3.getId()).isNotEqualTo(rate1.getId());
    Assertions.assertThat(rate3.getRate()).isNotEqualTo(rate1.getRate());
    Assertions.assertThat(rate3).isNotSameAs(rate1);
  }
}
请参考以下页面
- 
- https://docs.spring.io/spring-boot/docs/2.7.5/reference/htmlsingle/#io.caching
 
 
- https://docs.spring.io/spring-framework/docs/5.3.23/reference/html/integration.html#cache