一、简介

在这个简短的教程中,我们将了解如何将Redis配置为 Spring Boot 缓存的数据存储。

2. 依赖关系

首先,让我们添加 spring-boot-starter-cachespring-boot-starter-data-redis 工件:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
    <version>2.4.3</version>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
    <version>2.4.3</version>
</dependency>

这些添加了缓存支持并引入了所有必需的依赖项。

3. 配置

通过添加上述依赖项和 @EnableCaching 注解,Spring Boot将自动配置一个具有默认缓存配置的 RedisCacheManager 。但是,我们可以在缓存管理器初始化之前通过几种有用的方式修改此配置。

首先,我们创建一个 RedisCacheConfiguration bean:

@Bean
public RedisCacheConfiguration cacheConfiguration() {
    return RedisCacheConfiguration.defaultCacheConfig()
      .entryTtl(Duration.ofMinutes(60))
      .disableCachingNullValues()
      .serializeValuesWith(SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer()));
}

这使我们能够 更好地控制默认配置 - 例如,我们可以设置所需的生存时间 (TTL) 值并自定义动态缓存创建的默认序列化策略。

接下来,为了完全控制缓存设置,让我们注册自己的 RedisCacheManagerBuilderCustomizer bean:

@Bean
public RedisCacheManagerBuilderCustomizer redisCacheManagerBuilderCustomizer() {
    return (builder) -> builder
      .withCacheConfiguration("itemCache",
        RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(10)))
      .withCacheConfiguration("customerCache",
        RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofMinutes(5)));
}

在这里,我们使用 RedisCacheManagerBuilderRedisCacheConfiguration 分别为 itemCachecustomerCache 配置 TTL 值 10 分钟和 5 分钟。这有助于进一步 微调每个缓存的缓存行为, 包括 值、键前缀和二进制序列化。

值得一提的是,Redis 实例的默认连接详细信息是 localhost:6379Redis 配置可用于进一步调整低级连接细节以及主机和端口。

4. 示例

在我们的示例中,我们有一个 ItemService 组件,用于从数据库检索项目信息。实际上,这代表了潜在的成本高昂的操作,并且是缓存的良好候选者。

首先,让我们使用嵌入式 Redis服务器为此组件创建集成测试:

@Import({ CacheConfig.class, ItemService.class})
@ExtendWith(SpringExtension.class)
@EnableCaching
@ImportAutoConfiguration(classes = { 
  CacheAutoConfiguration.class, 
  RedisAutoConfiguration.class 
})
class ItemServiceCachingIntegrationTest {

    @MockBean
    private ItemRepository mockItemRepository;

    @Autowired
    private ItemService itemService;

    @Autowired
    private CacheManager cacheManager;

    @Test
    void givenRedisCaching_whenFindItemById_thenItemReturnedFromCache() {
        Item anItem = new Item(AN_ID, A_DESCRIPTION);
        given(mockItemRepository.findById(AN_ID))
          .willReturn(Optional.of(anItem));

        Item itemCacheMiss = itemService.getItemForId(AN_ID);
        Item itemCacheHit = itemService.getItemForId(AN_ID);

        assertThat(itemCacheMiss).isEqualTo(anItem);
        assertThat(itemCacheHit).isEqualTo(anItem);

        verify(mockItemRepository, times(1)).findById(AN_ID);
        assertThat(itemFromCache()).isEqualTo(anItem);
    }
}

在这里,我们为缓存行为创建一个测试切片并调用 getItemForId 两次。第一次调用应从存储库获取该项目,但 第二次调用应从缓存返回该项目,而不调用存储库

最后,让我们使用 Spring 的 @Cacheable 注解启用缓存行为:

@Cacheable(value = "itemCache")
public Item getItemForId(String id) {
    return itemRepository.findById(id)
      .orElseThrow(RuntimeException::new);
}

这将应用缓存逻辑,同时依赖于我们之前配置的 Redis 缓存基础设施。有关控制 Spring 缓存抽象的属性和行为(包括数据更新和逐出)的更多详细信息,请参阅我们的Spring 缓存指南一文。

5. 结论

在本教程中,我们了解了如何使用 Redis 进行 Spring 缓存。

最初,我们描述了如何使用最少的配置自动配置 Redis 缓存。然后,我们研究了如何通过注册配置 bean 来进一步自定义缓存行为。

最后,我们创建了一个示例用例来在实践中演示这种缓存。

与往常一样,完整的源代码可以在 GitHub 上获取。