@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,調用了兩次,就判斷爲緩存沒有起作用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章