轻松使用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
广告
将在 10 秒后关闭
bannerAds