All Downloads are FREE. Search and download functionalities are using the official Maven repository.

cn.acyou.leo.framework.cache.CustomizeRedisCache Maven / Gradle / Ivy

package cn.acyou.leo.framework.cache;

import org.apache.commons.lang3.math.NumberUtils;
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.Arrays;
import java.util.List;

/**
 * @author youfang
 * @version [1.0.0, 2020/7/1]
 **/
public class CustomizeRedisCache extends RedisCache {
    private final RedisCacheWriter redisCacheWriter;
    private final RedisCacheConfiguration configuration;
    //校验规则:获取时间
    private static final String SPLITTER = "#";

    /**
     * Create new {@link RedisCache}.
     *
     * @param name        must not be {@literal null}.
     * @param cacheWriter must not be {@literal null}.
     * @param cacheConfig must not be {@literal null}.
     */
    protected CustomizeRedisCache(String name, RedisCacheWriter cacheWriter, RedisCacheConfiguration cacheConfig) {
        super(name, cacheWriter, cacheConfig);
        redisCacheWriter = cacheWriter;
        configuration = cacheConfig;
    }


    /**
     * 重写cache put 逻辑,引入自定义TTL 实现
     * 实现逻辑:
     * 1.通过获取@Cacheable 中的value ,然后根据约定好的特殊字符进行分割
     * 2.从分割结果集中获取设置的TTL 时间并将value 中的,然后给当前缓存设置TTL
     */
    @Override
    public void put(Object key, Object value) {
        String name = super.getName();
        //是否按照指定的格式
        if (name.contains(SPLITTER)) {
            List keyList = Arrays.asList(name.split(SPLITTER));
            if (keyList.size() != 2) {
                throw new IllegalArgumentException("@Cacheable value = " + name + " not Allow !");
            }
            //获取键值
            String finalName = keyList.get(0);
            //获取TTL 执行时间
            String expireName = keyList.get(1);
            if (!NumberUtils.isCreatable(expireName)) {
                //不是时间类型
                throw new IllegalArgumentException("@Cacheable value = " + name + " not Allow ! ttl invalid");
            }
            long ttl = Long.parseLong(expireName);

            //获取缓存value
            Object cacheValue = preProcessCacheValue(value);
            //获取value 为null 时,抛出异常
            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));
            }
            //插入时添加时间
            redisCacheWriter.put(finalName, serializeCacheKey(createCacheKey(key)), serializeCacheValue(cacheValue), Duration.ofSeconds(ttl));

        }else {
            //原来逻辑处理
            super.put(key, value);
        }
    }

    @Override
    protected String createCacheKey(Object key) {
        String convertedKey = convertKey(key);
        if (!configuration.usePrefix()) {
            return convertedKey;
        }
        return prefixCacheKey(convertedKey);
    }


    private String prefixCacheKey(String key) {
        String name = super.getName();
        if (name.contains(SPLITTER)) {
            List keyList = Arrays.asList(name.split(SPLITTER));
            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;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy