作者最近在开发公司项目时使用到 redis 缓存 , 并在翻看前人代码时,看到了一种关于 @Cacheable 注解的自定义缓存有效期的解决方案,感觉比较实用,因此作者自己拓展完善了一番后分享给各位 。
Spring 缓存常规配置Spring Cache 框架给我们提供了 @Cacheable 注解用于缓存方法返回内容 。但是 @Cacheable 注解不能定义缓存有效期 。这样的话在一些需要自定义缓存有效期的场景就不太实用 。
按照 Spring Cache 框架给我们提供的 RedisCacheManager 实现,只能在全局设置缓存有效期 。这里给大家看一个常规的 CacheConfig 缓存配置类,代码如下,
@EnableCaching@Configurationpublic class CacheConfig extends CachingConfigurerSupport {...private RedisSerializer<String> keySerializer() {return new StringRedisSerializer();}private RedisSerializer<Object> valueSerializer() {return new GenericFastJsonRedisSerializer();}public static final String CACHE_PREFIX = "crowd:";@Beanpublic CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {// 配置序列化(解决乱码的问题)RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()//设置key为String.serializeKeysWith(RedisSerializationContext.SerializationPAIr.fromSerializer(keySerializer()))//设置value为自动转Json的Object.serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer())).computePrefixWith(name -> CACHE_PREFIX + name+ ":").entryTtl(Duration.ofSeconds(600));RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(Objects.requireNonNull(redisConnectionFactory));return new RedisCacheManager(redisCacheWriter, config);}}
这里面简单对 RedisCacheConfiguration 缓存配置做一下说明:
- serializeKeysWith():设置 Redis 的 key 的序列化规则 。
- erializeValuesWith():设置 Redis 的 value 的序列化规则 。
- computePrefixWith():计算 Redis 的 key 前缀 。
- entryTtl():全局设置 @Cacheable 注解缓存的有效期 。
@Cacheable(value = https://www.isolves.com/it/cxkf/jiagou/2023-11-09/"configCache", key = "#root.methodName + '_' + #root.args[0]")@Overridepublic String getValueByKey(String key) {QueryWrApper wrapper = new QueryWrapper<>();wrapper.eq("configKey", key);Config config = getOne(wrapper);if (config == null) {return null;}return config.getConfigValue();}
执行此方法后,Redis 中缓存 key 名称如下,crowd:configCache:getValueByKey_sys.name
文章插图
图片
TTL 过期时间是 287,跟我们全局设置的 300 秒基本是一致的 。此时假如我们想把 getValueByKey 方法的缓存有效期单独设置为 600 秒 , 那我们该如何操作嘞?
@Cacheable 注解默认是没有提供有关缓存有效期设置的 。想要单独修改 getValueByKey 方法的缓存有效期只能修改全局的缓存有效期 。那么有没有别的方法能够为 getValueByKey 方法单独设置缓存有效期嘞?当然是有的,大家请往下看 。
自定义 MyRedisCacheManager 缓存其实我们可以通过自定义 MyRedisCacheManager 类继承 Spring Cache 提供的 RedisCacheManager 类后,重写 createRedisCache(String name, RedisCacheConfiguration cacheConfig) 方法,代码如下 ,
【Spring Cache 缓存注解这样用,实在是太香了!】
public class MyRedisCacheManager extends RedisCacheManager {public MyRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {super(cacheWriter, defaultCacheConfiguration);}@Overrideprotected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {String[] array = StringUtils.split(name, "#");name = array[0];// 解析 @Cacheable 注解的 value 属性用以单独设置有效期if (array.length > 1) {long ttl = Long.parseLong(array[1]);cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(ttl));}return super.createRedisCache(name, cacheConfig);}}
MyRedisCacheManager 类逻辑如下,- 继承 Spring Cache 提供的 RedisCacheManager 类 。
- 重写 createRedisCache(String name, RedisCacheConfiguration cacheConfig) 方法 。
推荐阅读
- java中如何实现本地缓存?
- 影视大全能咋样离线缓存
- 一文带你了解Spring Actuator
- Springboot之把外部依赖包纳入Spring容器管理的两种方式
- SpringBoot接口参数校验N种实用技巧大揭秘
- Springboot 框架中事件监听和发布机制详细介绍
- Spring的BeanFactory与FactoryBean的区别,你现在懂了吗?
- 如何将本地jar文件打包到 springboot 执行jar文件中
- 认识一些常见的Spring Boot内置Health Indicator
- 影视大全能怎么样离线缓存