@Cacheable有效性检查

在使用springboot开发项目的时候,我们经常会用到缓存,一般就是通过注解@Cacheable来进行缓存设置。

我们代码是写了@Cacheable,我们以为能生效,但有时候因为一些原因,导致缓存不生效,程序也能正常运行,而我们却蒙在鼓里。如果是redis,虽然可以通过客户端去登录服务器查看有没有缓存,但也十分麻烦。

为了省点事,所以想到使用AOP来自动进行缓存检查,如果没有生效,就打印一些信息提示我们。

实现步骤很简单,只需要在springboot工程中添加上一个AOP类即可,并在配置文件中添加cacheable.check.switch=1

/**
 * 不要设置order,否则该AOP将会在@Cacheable之前执行,就无法检测缓存是否起作用了
 * 仅支持对方法级的@Cacheable进行检测,默认是以方法的所有参数作为key
 * 不支持缓存缓存更新,重新缓存的情况(会判断为缓存失效,可以自己完善实现处理@CacheEvict)
 */
@Aspect
@Component
@ConditionalOnProperty(name = "cacheable.check.switch",havingValue = "1")
public class CacheableCheckAop {
    //针对每个缓存,都有自己的一个set
    private Map<String, Set<String>> cache = new ConcurrentHashMap<>();
    //存放失效缓存的集合
    private Set<String> unValidCache = new HashSet<>();

    @Around("@annotation(cacheable)")
    public Object before(ProceedingJoinPoint joinPoint, Cacheable cacheable) throws Throwable{
        Object[] args = joinPoint.getArgs();
        String value = String.join("_", cacheable.value());
        if(!unValidCache.contains(value)) {
            if (!cache.containsKey(value)) {
                synchronized (cache) {
                    if (!cache.containsKey(value)) {
                        cache.put(value, new HashSet<>());
                    }
                }
            }
            String key = Arrays.stream(args).map(String::valueOf).collect(Collectors.joining("_"));
            Set<String> set = cache.get(value); //同一个缓存同一个key,如果多次调用了,说明缓存失效
            if (set.contains(key)) {
                System.err.println(value + "缓存无效,key:" + key);
                unValidCache.add(value);
            } else {
                set.add(key);
            }
        }
        try {
            return joinPoint.proceed();
        }finally {
        }
    }
}

缓存失效的情况:

1.工程中忘记打开@EnableCaching

2.方法调用同一个类的另一个注解了@Cacheable方法

例如上面的这些,该AOP都可以提示缓存失效,不用我们再人为去检查了。

 

总结:

通过AOP,在原有缓存基础上,再实现我们的简单缓存,如果相同的key,调用了两次,就判断为缓存没有起作用

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值