做网站主机要求,淘宝网站建设流程,营销型企业网站怎么建站,wordpress信息流广告一、自定义全局缓存key和双冒号替换
使用 Redis的客户端 Spring Cache时#xff0c;会发现生成 key中会多出一个冒号#xff0c;而且有一个空节点的存在。
查看源码可知#xff0c;这是因为 Spring Cache默认生成key的策略就是通过两个冒号来拼接。 同时 Spring Cache缓存…一、自定义全局缓存key和双冒号替换
使用 Redis的客户端 Spring Cache时会发现生成 key中会多出一个冒号而且有一个空节点的存在。
查看源码可知这是因为 Spring Cache默认生成key的策略就是通过两个冒号来拼接。 同时 Spring Cache缓存到 Redis的 key为Cache注解的value|cacheNames的值与其 key的值的拼接。 我们可以自定义 CacheKeyPrefix来替换双冒号也可以自定义全局缓存 key的前缀。 /*** 项目名*/private final static String SPRING_APPLICATION_NAME ws;/*** Cache 默认的 key前缀为空key的格式为Cacheable注解上的信息 value|cacheNames::key。* 自定义需求* 1、key前缀分隔符:: 不习惯换成:前缀分隔符。* 2、在 Cache相关注解 key的生成规则上添加全局缓存 key的前缀。*/private static final CacheKeyPrefix CUSTOM_CACHE_KEY_PREFIX cacheName - SPRING_APPLICATION_NAME : cacheName0 :;二、自定义过期时间
CacheManager 是 Spring 各种缓存的抽象接口。抽象的意义在于屏蔽不同实现细节的差异和提供扩展性。
对于 Spring Cache的缓存注解原生没有额外提供一个指定 ttl 的配置它是不支持在注解上添加过期时间的。
实际的业务场景中如果希望通过缓存注解指定过期时间TTL我们就需要自定义 RedisCacheManager来完成。
自定义TTL约定 1、支持使用 Cache注解的value|cacheNames来自定义过期时间。#ttlOfSecond不作为key的一部分。 示例value|cacheNames “keyName#ttlOfSecond”。 keyName为业务缓存key。#为自定义TTL连接符。ttlOfSecond为过期时间单位秒。 2、Spring Cache缓存到 Redis的 key需要过滤掉 #ttlOfSecond这部分。
实现逻辑步骤
1、自定义缓存管理器并继承RedisCacheManager同时重写createRedisCache方法2、将默认的缓存管理器改成我们自定义的缓存管理器
1、自定义缓存管理器
/*** 自定义 RedisCacheManager配置。*/
Slf4j
public class CustomRedisCacheManager extends RedisCacheManager {/*** 项目名*/private final static String SPRING_APPLICATION_NAME ws;/*** 自定义缓存参数的TTL分隔符* 示例value|cacheNames “keyName#ttlOfSecond”。*/private static final String CUSTOM_TTL_SEPARATOR #;public CustomRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {super(cacheWriter, defaultCacheConfiguration);}/*** param name must not be {literal null}. 业务 Cache注解的value|cacheNames* param cacheConfig can be {literal null}.* return*/Overrideprotected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) {Duration ttl getTtlByCustomName(name);if (ttl null) {// 如果自定义 TTL为空则设置全局 TTL为7天。ttl Duration.ofDays(7);}/*** Cache缓存配置*/cacheConfig cacheConfig.computePrefixWith(CUSTOM_CACHE_KEY_PREFIX) // 设置缓存key.entryTtl(ttl) // 设置缓存的过期时间查询不会更新过期时间;return super.createRedisCache(name, cacheConfig);}/*** Cache 默认的 RedisKey的格式为Cacheable注解上的信息 value|cacheNames::key。* 自定义需求* 1、key前缀分隔符:: 不习惯换成:前缀分隔符。* 2、在 Cache相关注解 key的生成规则上添加全局缓存 key的前缀。*/private static final CacheKeyPrefix CUSTOM_CACHE_KEY_PREFIX cacheName - {// 过滤掉自定义的 TTL分隔符String cacheName0 cacheName.split(CUSTOM_TTL_SEPARATOR)[0];return SPRING_APPLICATION_NAME : cacheName0 :;};/*** 根据 TTL分隔符拆分字符串并进行过期时间 TTL的解析** param name 业务 Cache注解的value|cacheNames* return*/private Duration getTtlByCustomName(String name) {if (StringUtils.isBlank(name)) {return null;}/*** 根据 TTL分隔符拆分字符串并进行过期时间 TTL的解析* 数组元素0 缓存的名称* 数组元素1 缓存过期时间TTL*/String[] cacheParams name.split(CUSTOM_TTL_SEPARATOR);if (cacheParams.length 1) {// 如果 TTL解析异常或者小于等于0则返回null;Long ttl null;try {ttl Long.parseLong(cacheParams[1]);} catch (NumberFormatException e) {log.debug( CacheManager 解析自定义 TTL异常e.getMessage {}, e.getMessage());}if (ttl ! null ttl 0) {return Duration.ofSeconds(ttl);}}return null;}
}
2、注入自定义缓存管理器
在自定义的 CacheConfiguration类中注入我们自定义的缓存管理器。
EnableCaching
Configuration
public class CacheConfiguration {Beanpublic CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {// 初始化一个RedisCacheWriterRedisCacheWriter redisCacheWriter RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory);// 初始化一个RedisCacheConfigurationRedisCacheConfiguration defaultCacheConfig RedisCacheConfiguration.defaultCacheConfig();// 返回一个自定义的CacheManagerreturn new CustomRedisCacheManager(redisCacheWriter, defaultCacheConfig);}}3、业务使用 Cacheable(value userCache_#120, key #id, unless #resultnull)//Cacheable(value userCache_, key #id, unless #resultnull)//Cacheable(value userCache_#0asa, key #id, unless #resultnull)Overridepublic UserDTO getById(Long id) {if (id null || id 0L) {return null;}UserDO userDO userMapper.selectById(id);return do2DTO(userDO);}– 求知若饥虚心若愚。