@Override @Cacheable(cacheNames = "cache#45", key = "#key") public String test(String key) { System.out.println(key); return "12345"; }
通过cacheNames所传递的值进行处理来设置过期时间,如:cache#45 cache代表原来的前缀, #45 表示45秒的存活时间
实现:1.重新实现RedisCache
package com.sixi.ordercenter.business.config; import com.google.common.base.Splitter; import com.google.common.collect.Lists; import org.springframework.data.redis.cache.RedisCache; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheWriter; import java.time.Duration; import java.util.List; import java.util.regex.Pattern; /** * @author : chenjie * @date : 2019-09-30 13:44 */ public class CustomizeRedisCache extends RedisCache { private RedisCacheWriter cacheWriter; private RedisCacheConfiguration configuration; //校验规则:获取时间 String REGEX_STR = ".*\\#\\d+$"; /** * Create new {@link RedisCache}. * * @param name must not be {@literal null}. * @param redisCacheWriter must not be {@literal null}. * @param cacheConfig must not be {@literal null}. */ protected CustomizeRedisCache(String name, RedisCacheWriter redisCacheWriter, RedisCacheConfiguration cacheConfig) { super(name, redisCacheWriter, cacheConfig); cacheWriter = redisCacheWriter; configuration = cacheConfig; } /** 主要实现逻辑 **/ @Override public void put(Object key, Object value) { String name = super.getName(); //是否按照指定的格式 if (Pattern.matches(REGEX_STR, name)) { List<String> keyList = Lists.newArrayList(Splitter.on("#").split(name)); String finalName = keyList.get(0); Long ttl = Long.valueOf(keyList.get(1)); Object cacheValue = preProcessCacheValue(value); if (!isAllowNullValues() && cacheValue == null) { throw new IllegalArgumentException(String.format( "Cache '%s' does not allow 'null' values. Avoid storing null via '@Cacheable(unless=\"#result == null\")' or configure RedisCache to allow 'null' via RedisCacheConfiguration.", name)); } //插入时添加时间 cacheWriter.put(finalName, serializeCacheKey(createMyCacheKey(key)), serializeCacheValue(cacheValue), Duration.ofSeconds(ttl)); } else { //原来逻辑处理 super.put(key, value); } } /** 用户key的生成时不含有#45的前缀 **/ protected String createMyCacheKey(Object key) { String convertedKey = convertKey(key); if (!configuration.usePrefix()) { return convertedKey; } return prefixCacheKey(convertedKey); } /** 去除下#45 的格式影响 **/ private String prefixCacheKey(String key) { String name = super.getName(); if (Pattern.matches(REGEX_STR, name)) { List<String> keyList = Lists.newArrayList(Splitter.on("#").split(name)); String finalName = keyList.get(0); return configuration.getKeyPrefixFor(finalName) + key; } // allow contextual cache names by computing the key prefix on every call. return configuration.getKeyPrefixFor(name) + key; } }
2.实现RedisCacheManager
import org.springframework.data.redis.cache.RedisCache; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheWriter; import java.util.Map; /** * @author : chenjie * @date : 2019-09-30 15:31 */ public class MyRedisCacheManage extends RedisCacheManager { private final RedisCacheWriter cacheWriter; private final RedisCacheConfiguration defaultCacheConfig; /** 用于返回自定义的redisCache **/ @Override protected RedisCache createRedisCache(String name, RedisCacheConfiguration cacheConfig) { return new CustomizeRedisCache(name, cacheWriter, cacheConfig != null ? cacheConfig : defaultCacheConfig); } public MyRedisCacheManage(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) { super(cacheWriter, defaultCacheConfiguration); this.cacheWriter = cacheWriter; this.defaultCacheConfig = defaultCacheConfiguration; } public MyRedisCacheManage(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, String... initialCacheNames) { super(cacheWriter, defaultCacheConfiguration, initialCacheNames); this.cacheWriter = cacheWriter; this.defaultCacheConfig = defaultCacheConfiguration; } public MyRedisCacheManage(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, boolean allowInFlightCacheCreation, String... initialCacheNames) { super(cacheWriter, defaultCacheConfiguration, allowInFlightCacheCreation, initialCacheNames); this.cacheWriter = cacheWriter; this.defaultCacheConfig = defaultCacheConfiguration; } public MyRedisCacheManage(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, Map<String, RedisCacheConfiguration> initialCacheConfigurations) { super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations); this.cacheWriter = cacheWriter; this.defaultCacheConfig = defaultCacheConfiguration; } public MyRedisCacheManage(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration, Map<String, RedisCacheConfiguration> initialCacheConfigurations, boolean allowInFlightCacheCreation) { super(cacheWriter, defaultCacheConfiguration, initialCacheConfigurations, allowInFlightCacheCreation); this.cacheWriter = cacheWriter; this.defaultCacheConfig = defaultCacheConfiguration; } }
3.注入容器中
@Bean public RedisCacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) { //初始化一个RedisCacheWriter RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory); //设置CacheManager的值序列化方式为json序列化 RedisSerializer<Object> jsonSerializer = new GenericFastJsonRedisSerializer(); RedisSerializationContext.SerializationPair<Object> pair = RedisSerializationContext.SerializationPair.fromSerializer(jsonSerializer); RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig().serializeValuesWith(pair); //初始化RedisCacheManager return new MyRedisCacheManage(redisCacheWriter, defaultCacheConfig); }
逻辑比较简单,只是在插入时把cacheNames中的值包含过期时间进行传递,然后获取设置就行