当前位置:   article > 正文

Springboot @Cacheable注解中 自定义处理value/cacheNames实现自定义过期时间_@cacheable每个key都设置过期时间

@cacheable每个key都设置过期时间

概要

`Springboot @Cacheable注解中 自定义处理value/cacheNames实现自定义过期时间

例如:

@Cacheable(value = “user#200#s”) 实现rediskey为user的过期时间为200s

技术细节

在项目中引入这些配置:

1.自定义@Cacheable中value字段的解析处理
public class MyRedisCacheManager extends RedisCacheManager {

    private final static List<String> optionalUnits = ListUtil.of("ms", "s", "m", "h", "d");

    private final static String defaultTimeUnit = "s";

    public MyRedisCacheManager(RedisCacheWriter cacheWriter, RedisCacheConfiguration defaultCacheConfiguration) {
        super(cacheWriter, defaultCacheConfiguration);
    }

    /**
     * 使用@Cacheable时,value中通过#号隔开,第一位是name,第二位是有效时间,第三位是单位,默认可以不传(默认为秒s)
     * 第二位仅限填写:ms,s,m,h,d其中,ms:毫秒,s:秒,m:分钟,h:小时,d:天
     *
     * @param name
     * @param cacheConfig
     * @return
     */
    @Override
    protected 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 = setValidityPeriod(array, cacheConfig);
        }

        return super.createRedisCache(name, cacheConfig);
    }

    /**
     * 设置有效期
     * 根据时间单位将需要设置的有效期转换为对应的Duration对象
     *
     * @param array       时间单位数组
     * @param cacheConfig 缓存配置
     * @return 设置有效期后的缓存配置
     */
    private RedisCacheConfiguration setValidityPeriod(String[] array, RedisCacheConfiguration cacheConfig) {

        String unit = defaultTimeUnit;  // 设置默认时间单位

        if (array.length > 2) {  // 如果数组长度大于2
            String tempUnit = array[2];  // 创建临时变量tempUnit,并赋值为数组第3个元素
            if (!optionalUnits.contains(tempUnit)) {  // 如果临时变量tempUnit不在optionalUnits中
                throw new RuntimeException("Incorrect time unit setting");  // 抛出运行时异常,提示时间单位设置不正确
            }

            unit = tempUnit;  // 将unit的值设置为tempUnit
        }

        switch (unit) {
            case "ms":
                // 单位为毫秒
                cacheConfig = cacheConfig.entryTtl(Duration.ofMillis(Long.parseLong(array[1])));
                break;
            case "s":
                // 单位为秒
                cacheConfig = cacheConfig.entryTtl(Duration.ofSeconds(Long.parseLong(array[1])));
                break;
            case "m":
                // 单位为分钟
                cacheConfig = cacheConfig.entryTtl(Duration.ofMinutes(Long.parseLong(array[1])));
                break;
            case "h":
                // 单位为小时
                cacheConfig = cacheConfig.entryTtl(Duration.ofHours(Long.parseLong(array[1])));
                break;
            case "d":
                // 单位为天
                cacheConfig = cacheConfig.entryTtl(Duration.ofDays(Long.parseLong(array[1])));
                break;
            default:
                break;
        }

        return cacheConfig;

    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
2.Redis使用FastJson序列化
/**
 * Redis使用FastJson序列化
 * 
 * @author logistics
 */
public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{
    public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

    private Class<T> clazz;

    public FastJson2JsonRedisSerializer(Class<T> clazz)
    {
        super();
        this.clazz = clazz;
    }

    @Override
    public byte[] serialize(T t) throws SerializationException
    {
        if (t == null)
        {
            return new byte[0];
        }
        return JSON.toJSONString(t, JSONWriter.Feature.WriteClassName).getBytes(DEFAULT_CHARSET);
    }

    @Override
    public T deserialize(byte[] bytes) throws SerializationException
    {
        if (bytes == null || bytes.length <= 0)
        {
            return null;
        }
        String str = new String(bytes, DEFAULT_CHARSET);

        return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
3.redis配置
/**
 * redis配置
 *
 * @author 
 */
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
   

      private RedisSerializer<String> keySerializer() {
        // 用于序列化 Redis 的 key 的序列化规则
        return new StringRedisSerializer();
    }

    private RedisSerializer<Object> valueSerializer() {
        // 用于序列化 Redis 的 value 的序列化规则
        return new FastJson2JsonRedisSerializer(Object.class);
    }

    public static final String CACHE_PREFIX = "crowd:";

    /**
     * CacheManager 配置
     *
     * @param redisConnectionFactory Redis 连接工厂
     * @return CacheManager 实例
     */
    @Bean
    public CacheManager cacheManager(RedisConnectionFactory redisConnectionFactory) {
        return new MyRedisCacheManager(RedisCacheWriter.nonLockingRedisCacheWriter(redisConnectionFactory), defaultCacheConfig());
    }

    /**
     * 设置 Redis 的 key 的序列化规则。
     * 设置 Redis 的 value 的序列化规则。
     * 计算 Redis 的 key 前缀。
     * 全局设置 @Cacheable 注解缓存的有效期。
     *
     * @return RedisCacheConfiguration 实例
     */
    private RedisCacheConfiguration defaultCacheConfig() {
        return RedisCacheConfiguration.defaultCacheConfig()
                .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(keySerializer()))
                .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(valueSerializer()))
//                .computePrefixWith(name -> CACHE_PREFIX + name  + ":")
//                .entryTtl(Duration.ofSeconds(600))
                ;
    }


    
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
常用属性说明

● cacheNames/value :用来指定缓存组件的名字
● key :缓存数据时使用的 key,可以用它来指定。默认是使用方法参数的值。(这个 key 你可以使用 spEL 表达式来编写)
● keyGenerator :key 的生成器。 key 和 keyGenerator 二选一使用
● cacheManager :可以用来指定缓存管理器。从哪个缓存管理器里面获取缓存。
● condition :可以用来指定符合条件的情况下才缓存
● unless :否定缓存。当 unless 指定的条件为 true ,方法的返回值就不会被缓存。当然你也可以获取到结果进行判断。(通过 #result 获取方法结果)
● sync :是否使用异步模式。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/353157
推荐阅读
  

闽ICP备14008679号