Перейти к основному содержимому

Spring Boot Cache с Redis

· 3 мин. чтения

Задача: Наибольшая подстрока палиндром

Для заданной строки s, верните наибольшую подстроку палиндром входящую в s. Подстрока — это непрерывная непустая последовательность символов внутри строки. Стока является палиндромом, если она читается одинаково в обоих направлениях...

ANDROMEDA 42

1. Обзор

В этом кратком руководстве мы рассмотрим, как настроить Redis в качестве хранилища данных для кеша Spring Boot.

2. Зависимости

Для начала добавим артефакты spring-boot-starter-cache и spring-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 с конфигурацией кеша по умолчанию. Однако мы можем изменить эту конфигурацию до инициализации менеджера кэша несколькими полезными способами.

Во-первых, давайте создадим bean-компонент RedisCacheConfiguration :

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

Это дает нам больше контроля над конфигурацией по умолчанию. Например, мы можем установить желаемые значения времени жизни (TTL) и настроить стратегию сериализации по умолчанию для создания кеша в полете.

Чтобы иметь полный контроль над настройкой кэширования, давайте зарегистрируем наш собственный bean-компонент RedisCacheManagerBuilderCustomizer :

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

Здесь мы использовали RedisCacheManagerBuilder вместе с RedisCacheConfiguration для настройки значений TTL 10 и 5 минут для itemCache и customerCache соответственно. Это помогает дополнительно настроить поведение кэширования для каждого кэша , включая нулевые значения, префиксы ключей и двоичную сериализацию.

Стоит отметить, что сведения о соединении по умолчанию для экземпляра Redis — localhost:6379 . Конфигурацию Redis можно использовать для дальнейшей настройки низкоуровневых сведений о соединении вместе с хостом и портом.

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 .