SpringCache整合redis时,@CacheEvict , allEntries = true无效问题

SpringCache整合redis时,使用,发现缓存并没有删除

@CacheEvict(value = "ParkConfig",allEntries = true)
image.png

查看源代码CacheAspectSupport,这里调用的是doClear方法


image.png

查看doClear方法


image.png

这里调用了cache的clear方法,我们这里整合的REDIS,看一下redis的实现类


image.png

RedisCache.clear调用了cacheWriter的clean方法


image.png

打开DefaultRedisCacheWriter.clean 方法.DEBUG一下


image.png

debug发现 pattern这个变量和redis客户端里面的键不一致,命令也获取不到任何数据


image.png
image.png
image.png

改成相应的键可以


image.png

原因:由于redis被多个程序使用,所以我们在使用redis的时候给所有缓存都添加了一个前缀,而clear方法是直接使用的connect对象,在使用键的时候没有根据这个情况进行序列化键,


image.png

要解决这个问题也很简单,DefaultRedisCacheWriter不允许继承,写一个代理类,修改clean方法

package cn.akeparking.middleware.cache.redis;

import org.springframework.data.redis.cache.RedisCacheWriter;

import java.time.Duration;

/**
 * @Description
 * @Author Mahz
 * @Date2021/8/18 14:16
 **/
public class MiddlewareRedisCacheWriterProxy implements RedisCacheWriter {

    RedisCacheWriter redisCacheWriter;

    MiddlewareKeySerializer middlewareKeySerializer;

    public MiddlewareRedisCacheWriterProxy(RedisCacheWriter redisCacheWriter, MiddlewareKeySerializer middlewareKeySerializer) {
        this.redisCacheWriter = redisCacheWriter;
        this.middlewareKeySerializer = middlewareKeySerializer;
    }

    @Override
    public void put(String name, byte[] key, byte[] value, Duration ttl) {
        redisCacheWriter.put(name, key, value, ttl);
    }

    @Override
    public byte[] get(String name, byte[] key) {
        return redisCacheWriter.get(name, key);
    }

    @Override
    public byte[] putIfAbsent(String name, byte[] key, byte[] value, Duration ttl) {
        return redisCacheWriter.putIfAbsent(name, key, value, ttl);
    }

    @Override
    public void remove(String name, byte[] key) {
        redisCacheWriter.remove(name, key);
    }

    @Override
    public void clean(String name, byte[] pattern) {
        pattern = middlewareKeySerializer.serialize(new String(pattern));
        redisCacheWriter.clean(name, pattern);
    }
}

        //初始化一个RedisCacheWriter
        RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(connectionFactory);

        MiddlewareRedisCacheWriterProxy middlewareRedisCacheWriterProxy = new MiddlewareRedisCacheWriterProxy(redisCacheWriter,KeySerializer());


        RedisTemplate redisTemplate = redisTemplate(connectionFactory);
        RedisSerializationContext.SerializationPair value = RedisSerializationContext.SerializationPair
                .fromSerializer(redisTemplate.getValueSerializer());

        RedisSerializationContext.SerializationPair key = RedisSerializationContext.SerializationPair
                .fromSerializer(redisTemplate.getKeySerializer());

        RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
                .serializeValuesWith(value)
                .serializeKeysWith(key);
        defaultCacheConfig.entryTtl(Duration.ofDays(1));

        return new RedisCacheManager(middlewareRedisCacheWriterProxy, defaultCacheConfig);
 
 

已经能够正常删除


image.png

你可能感兴趣的:(SpringCache整合redis时,@CacheEvict , allEntries = true无效问题)