计划 Spring 缓存逐出?

Schedule Spring cache eviction?

是否可以将 spring 缓存逐出安排在每天午夜?

我已阅读 Springs Cache Docs 并没有发现任何有关计划缓存逐出的内容。

我需要每天清除缓存并重新缓存它以防我的应用程序外发生一些变化。

Spring 缓存框架是事件驱动的,即 @Cacheable@CacheEvict 仅在调用相应方法时才会触发。

但是您可以利用底层缓存提供程序(记住 Spring 缓存框架只是一个抽象概念,它本身并不提供缓存解决方案)使自己缓存。例如 EhCache 有一个 属性 即。 timeToLiveSeconds 指示缓存激活前的时间。但这不会为您重新填充缓存,除非调用 @Cacheable 注释方法。

因此,为了在特定时间(比如提到的午夜)进行缓存逐出和重新填充,请考虑在 Spring 中实现后台 scheduled service,这将触发根据需要缓存逐出和重新填充。预期的行为不是开箱即用的。

希望这对您有所帮助。

尝试使用@Scheduled 示例:

@Scheduled(fixedRate = ONE_DAY)
@CacheEvict(value = { CACHE_NAME })
public void clearCache() {  
    log.debug("Cache '{}' cleared.", CACHE);    
}

您还可以将 cron 表达式与 @Scheduled 一起使用。

我知道这个问题很老,但我找到了一个更适合我的解决方案。也许这会对其他人有所帮助。

因此,确实可以进行预定的缓存逐出。这是我在我的案例中所做的。

注解@Scheduled 和@CacheEvict 似乎不能一起工作。 因此,您必须将调度方法和缓存逐出方法分开。 但是由于整个机制是基于代理的,只有外部调用 class 的 public 方法才会触发缓存逐出。这是因为相同 class 方法之间的内部调用不通过 Spring 代理。

我设法用与 Celebes 相同的方式修复它(见评论),但进行了改进以避免两个组件。

@Component
class MyClass
{

    @Autowired
    MyClass proxiedThis; // store your component inside its Spring proxy.

    // A cron expression to define every day at midnight
    @Scheduled(cron ="0 0 * * *")
    public void cacheEvictionScheduler()
    {
        proxiedThis.clearCache();
    }

    @CacheEvict(value = { CACHE_NAME })
    public void clearCache()
    {
        // intentionally left blank. Or add some trace info.
    }    
}

如果在带参数的方法上使用@Cacheable,永远不要忘记@CacheEvict 上的allEntries=true 注解属性,否则你的调用只会逐出你给 clearCache() 方法的关键参数,它什么都不是 => 你不会从缓存中驱逐任何东西。

也许不是最优雅的解决方案,但是@CacheEvict没有用,所以我直接去了CacheManager

此代码通过调度程序清除名为 foo 的缓存:

class MyClass {

    @Autowired CacheManager cacheManager;

    @Cacheable(value = "foo")
    public Int expensiveCalculation(String bar) {
        ...
    }

    @Scheduled(fixedRate = 60 * 1000);
    public void clearCache() {
        cacheManager.getCache("foo").clear();
    }
}

请相应地遵循以下 code.change cron 表达式。我设置了3分钟

  1. 创建 class。

  2. 在 class.

    中使用下面的方法
    class A 
    {
    @Autowired CacheManager cacheManager;
    
    @Scheduled(cron ="0 */3 * ? * *")
        public void cacheEvictionScheduler()
        {
             logger.info("inside scheduler start");
            //clearCache();
             evictAllCaches();
            logger.info("inside scheduler end");
        }
    
    public void evictAllCaches() {
             logger.info("inside clearcache");
            cacheManager.getCacheNames().stream()
              .forEach(cacheName -> cacheManager.getCache(cacheName).clear());
        }
    }