在 Spring Boot 中使用 Redis 缓存

在本文中,我们将看到如何将 Redis Cache 与 Spring Boot 集成。我们将学习如何在 Spring 启动缓存中配置 Redis 数据。

让我们先看看将 Redis 导入 Spring 启动应用程序所需的依赖项。

依赖关系

// Adding spring-boot cache & redis dependencies
<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>

配置

添加 Redis 依赖项后,您现在需要执行一些配置,以便它可以在您的项目中使用。Spring Boot 将自动配置一个 Redis 缓存管理器,但具有默认属性。我们可以修改此配置并根据我们的要求进行更改。

@Bean
public RedisCacheConfiguration cacheConfiguration() {
   return RedisCacheConfiguration.defaultCacheConfig()
   .entryTtl(Duration.ofMinutes(60)) // 更改缓存 TTL
   .disableCachingNullValues()
   .serializeValuesWith(SerializationPair.fromSerializer(newGenericJackson2JsonRedisSerializer())); 
   //定义序列化以检索数据
}

修改配置使我们可以更好地控制基本缓存配置。例如,我们可以更改默认的生存时间值并将默认序列化策略自定义为动态缓存创建,如上所示。

示例

让我们举一个例子,我们有一个EmployeeService组件,它从数据库中检索员工信息。由于我们需要获取多个事情的员工详细信息,我们需要这些数据快速,这就是我们使用 Redis 缓存的原因。让我们为它创建一个集成测试

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

   @MockBean
   private EmployeeRepository mockEmployeeRepository;

   @Autowired
   private EmployeeService employeeService;

   @Autowired
   private CacheManager cacheManager;

   @Test
   void
   givenRedisCaching_whenFindEmployeeById_thenEmployeeReturnedFromCache() {
      Employee employee = new Employee(id, A_DESCRIPTION);
      given(mockEmployeeRepository.findById(id))
      .willReturn(Optional.of(employee));

      Employee employeeNotFromCache = employeeService.getEmployeeById(id);
      Employee employeeFromCache = employeeService.getEmployeeById(id);

      assertThat(employeeNotFromCache).isEqualTo(employee);
      assertThat(employeeFromCache).isEqualTo(employee);

      verify(mockEmployeeRepository, times(1)).findById(id);
      assertThat(employeeFromCache()).isEqualTo(employee);
   }
}

从缓存中检索数据

@Cacheable(value = "employeeCache")
public Employee getEmployeeForId(String id) {
   return employeeRepository.findById(id)
      .orElseThrow(RuntimeException::new);
}

我们已经调用了getEmployeeById()两次。第一次调用应该从存储库中获取项目,而第二次调用应该从缓存中返回相同的员工对象,而不调用存储库。