Малый концентратор ведет к чтению:
Я не знаю, вы установили время истечения срока действия кеша, попробуйте?
В предыдущей статье мы использовали Springboot для интеграции Redis и использовали RedisTemplate для управления кэшированными данными, которые можно использовать гибко.
Сегодня мы поговорим об аннотации кэша Spring Cache, предоставляемой Spring. Spring поддерживает различные технологии кэширования: RedisCacheManager, EhCacheCacheManager, GuavaCacheManager и т. д. Перед использованием необходимо настроить компонент CacheManager.
После настройки используйте три часто используемые аннотации для кэширования данных:
- @Cacheable
- @CachePut
- @КэшЭвикт.
Что означают эти три аннотации, мы разберем их одну за другой позже.
1. Настройте RedisCacheManager
Как я только что сказал, сначала нам нужно настроить менеджер кеша, а затем мы можем использовать аннотации кеша для управления кешем. В предыдущей статье мы интегрировали Redis, теперь нам нужно только напрямую настроить RedisCacheManager.
- com.markerhub.config.RedisConfig
/**
* 配置一个CacheManager才能使用@Cacheable等注解
*
* 公众号:MarkerHub
*/
@Bean
public CacheManager cacheManager(RedisTemplate<String, Object> template) {
// 基本配置
RedisCacheConfiguration defaultCacheConfiguration =
RedisCacheConfiguration
.defaultCacheConfig()
// 设置key为String
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getStringSerializer()))
// 设置value 为自动转Json的Object
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getValueSerializer()))
// 不缓存null
.disableCachingNullValues()
// 缓存数据保存1小时
.entryTtl(Duration.ofHours(1));
// 够着一个redis缓存管理器
RedisCacheManager redisCacheManager =
RedisCacheManager.RedisCacheManagerBuilder
// Redis 连接工厂
.fromConnectionFactory(template.getConnectionFactory())
// 缓存配置
.cacheDefaults(defaultCacheConfiguration)
// 配置同步修改或删除 put/evict
.transactionAware()
.build();
return redisCacheManager;
}
В приведенной выше конфигурации большая часть кода аннотирована, нам нужно только настроить его в соответствии с нашими потребностями. Стратегия десериализации расширяет параметры исходного шаблона RedisTemplate.
- RedisCacheConfiguration
- RedisCacheManager
Есть еще один важный шаг, о котором нельзя забывать, необходимо включить поддержку функции кеширования Spring Cache, это очень просто, достаточно добавить аннотацию в RedisConfig:
@EnableCaching
написать пример
Выше мы настроили RedisCacheManager, чтобы помочь нам управлять кешем, а затем мы будем использовать аннотации Spring Cache для завершения тестирования кода.
Следующий пример может показаться немного грубым, если вы не знаете каких-то параметров, советую прочитать эту статью:https://blog.csdn.net/dreamhai/article/details/80642010
.
1. @Кэшируемый
Отмечается на методе или классе, чтобы указать, что метод или класс поддерживает кэширование. После того, как Spring вызовет метод идентификации аннотации, он кэширует возвращаемое значение в Redis, чтобы гарантировать, что возвращаемое значение будет получено непосредственно из кеша при следующем вызове метода с теми же условиями. Таким образом, нет необходимости повторно выполнять процесс бизнес-обработки способа, и повышается эффективность.
Три часто используемых параметра @Cacheable:
- cacheNames имена кешей
- key Кэшированный ключ, вам нужно обратить внимание на то, как ключ написан.
- условие кэширует условие выполнения и выполняется, когда оно возвращает true
@Slf4j
@Service
public class UserServiceImpl implements UserService {
@Override
@Cacheable(cacheNames = "cache_user", key="'user_' + #id")
public User getById(long id) {
log.info("进来查库了--------->{}", id);
User user = new User();
user.setId(1L);
user.setUsername("MarkerHub" + id);
return user;
}
}
Затем напишите конкретный звонок:
@RestController
public class UserController {
@Autowired
UserService userService;
@GetMapping("/u/{id}")
public User index(@PathVariable("id") Long id) {
User user = userService.getById(id);
return user;
}
}
Чтобы получить доступ к результатам теста, перейдите по ссылке:http://localhost:8080/u/12
,
Вывод консоли при первом вызове:
进来查库了--------->12
При повторном посещении во второй раз вывода дальше нет, что говорит о том, что бизнес-метод не введен, то есть результат получен в редисе и возвращен напрямую.
Взгляните на инструменты визуализации Redis:
Здесь вам нужно обратить внимание, что при настройке метода сериализации redis вы должны настроить следующий код, который ранее упоминался в redis конфигурации Springboot.
Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
serializer.setObjectMapper(objectMapper);
Если ваше сериализованное значение представляет собой просто данные json, это вызовет ошибку принудительного преобразования. Нужно обратить внимание!
2. @CacheEvict
Отмечено на методе, после выполнения метода соответствующий кеш удаляется по условию или ключу. Общие свойства:
- allEntries логический тип, указывающий, нужно ли очищать все элементы в кеше.
- key Кэшированный ключ, который необходимо удалить
@Override
@CacheEvict(cacheNames = "cache_user", allEntries = true)
public void update(User user) {
// 更新逻辑...
}
тогда,update
После выполнения методаcacheNames="cache_user"
Все кэши внутри будут удалены! Это тоже очень распространенный метод. Конечно, вы также можете написать это, чтобы удалить указанный кеш на основе ключа:
@Override
@CacheEvict(cacheNames = "cache_user", key = "'user_' + #user.id")
public void update(User user) {
// 更新逻辑...
}
3. @@CachePut
Помеченный метод не будет проверять, существует ли в кеше результат предыдущего выполнения перед выполнением, а будет выполнять метод каждый раз, и сохранять результат выполнения в указанном кеше в виде пары ключ-значение.
4. @Кэширование
Несколько аннотаций могут быть отмечены в аннотации, которая имеет три атрибута: cacheable, put и evict, которые используются для указания @Cacheable, @CachePut и @CacheEvict соответственно.
Дата истечения срока годности
Мы реализовали основные функции Spring Cache, интегрировав Redis какRedisCacheManger
, но, как мы все знаем, мы используем@Cacheable
При аннотировании нельзя давать кешу время истечения. Но иногда в некоторых сценариях нам нужно дать кешу время истечения срока действия!
Когда кеш не согласуется с данными базы данных, особенно важно автоматическое истечение срока действия — это способ обеспечить практический результат. Итак, как указать время истечения срока действия кеша Spring?
На самом деле нам не нужно интегрировать сторонние пакеты, такие как Redission и т.д. Мы настраиваемRedisCacheManager
На самом деле можно настроить время истечения, но это время истечения для кеша.
Что это означает? Например, если вы используете следующую аннотацию:
@Cacheable(cacheNames = "cache_user", key="'user_' + #id")
Мы можем указать cacheNames какcache_user
Срок действия кэша. Давайте рассмотримRedisCacheManager
начальная конфигурация.
выше вRedisCacheConfiguration
Наконец, мы настраиваем конфигурацию о времени истечения срока действия..entryTtl(Duration.ofHours(1))
, кэшированные данные хранятся в течение одного часа. И вRedisCacheManager
передай.cacheDefaults(defaultCacheConfiguration)
настроен. Эти две строки кода на самом деле говорят, что все кешированные данные по умолчанию сохраняются в течение часа.
По сравнению с предыдущим, мы единообразно настроили время истечения кэша на 1 час. Но это все еще относительно исправлено.Вообще говоря, мы хотим дать разным кешам разное время истечения, напримерcache_post
иcache_user
Разное время экспирации, так как это сделать? Можно ли это реализовать в конфигурации?
Ответ да, очень простой, вRedisCacheManager
Есть такой метод:
RedisCacheManagerBuilder withCacheConfiguration(String cacheName, RedisCacheConfiguration cacheConfiguration)
Вы можете присвоить каждому cacheName другую конфигурацию RedisCacheConfiguration. В предыдущей конфигурации мы настроили конфигурацию кеша по умолчанию. После этого метода мы можем указать конфигурацию кеша для кеша. Разница между каждой конфигурацией кеша на самом деле заключается во времени истечения срока действия. Поэтому мы берем метод для генерации конфигурации кеша, код выглядит следующим образом:
RedisCacheConfiguration getCacheConfigurationWithTtl(RedisTemplate<String, Object> template, long seconds) {
return RedisCacheConfiguration
.defaultCacheConfig()
// 设置key为String
.serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getStringSerializer()))
// 设置value 为自动转Json的Object
.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(template.getValueSerializer()))
// 不缓存null
.disableCachingNullValues()
// 缓存数据保存1小时
.entryTtl(Duration.ofSeconds(seconds));
}
Параметр секунд указывает время истечения срока действия кеша, поэтому мы должны настроить его в RedisCacheManager следующим образом:
RedisCacheManager redisCacheManager =
RedisCacheManager.RedisCacheManagerBuilder
// Redis 连接工厂
.fromConnectionFactory(template.getConnectionFactory())
.cacheDefaults(getCacheConfigurationWithTtl(template, 60 * 60))
.withCacheConfiguration("cache_user", getCacheConfigurationWithTtl(template, 60))
.withCacheConfiguration("cache_post", getCacheConfigurationWithTtl(template, 120))
// 配置同步修改或删除 put/evict
.transactionAware()
.build();
return redisCacheManager;
}
В соответствии с приведенной выше конфигурацией мы указываем cacheName следующим образом:
- время истечения срока действия cache_user составляет 60 секунд.
- cache_post истекает через 120 секунд
- Другое время истечения срока действия по умолчанию составляет 1 час.
Это то, что я рекомендую всем!
У многих людей есть другие реализации, такие как добавление после cacheNames#3600
, перехват#
Следующее число — это время истечения срока действия.
@Cacheable(cacheNames = "cache_user#3600", key="'user_' + #id")
Некоторые люди хотят дать ключу срок действия, поэтому они пишут так:
@Cacheable(cacheNames = "cache_user#3600", key="'user_' + #id + '#3600'")
На самом деле мне это не кажется нужным. Пишите прямо в настройках, просто и удобно!
заключительные замечания
Хорошо, это конец сегодняшней статьи, нажмите в правом нижнем углу, чтобы прочитать, а затем идите, ха-ха.
Рекомендуемое чтение:
Последние часто задаваемые вопросы и ответы на корпоративных интервью в 2020 году