安排Spring缓存驱逐?

时间:2017-03-09 06:11:57

标签: java spring spring-cache

是否有可能在每天午夜安排弹簧缓存驱逐?

我已阅读Springs Cache Docs,但未发现有关预定缓存逐出的信息。

我需要每天逐出缓存并在我的应用程序之外发生一些更改时重新缓存它。

6 个答案:

答案 0 :(得分:8)

尝试使用@Scheduled 例如:

@Scheduled(fixedRate = ONE_DAY)
@CacheEvict(value = { CACHE_NAME })
public void clearCache() {      
}

你也可以在@Scheduled中使用cron表达式。

答案 1 :(得分:1)

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

但是,您可以利用底层缓存提供程序(记住Spring缓存框架只是一个抽象,并且本身不提供缓存解决方案)来使缓存本身无效。例如,EhCache有一个属性即。 timeToLiveSeconds指示缓存处于活动状态的时间。但是,除非调用@Cacheable带注释的方法,否则不会为您重新填充缓存。

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

希望这有帮助。

答案 2 :(得分:1)

如果在带参数的方法上使用@Cacheable,则永远不要忘记@CacheEvict上的 allEntries = true 批注属性,否则您的调用只会逐出您为clearCache提供的关键参数( )方法,什么也不是=>您将不会从缓存中逐出任何内容。

答案 3 :(得分:1)

也许不是最优雅的解决方案,但这对我来说可以通过调度程序清除整个缓存。

我无法让@CacheEvict工作,所以我直接去了CacheManager

class MyClass {

    @Autowired CacheManager cacheManager;

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

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

答案 4 :(得分:1)

请遵循以下代码。相应地更改cron表达式。我已经设置了3分钟

  1. 创建一个类。

  2. 在类中使用以下方法。

    let rec find_dup a lst =
      match lst with
        | [] -> false
        | hd::tl -> if (hd == a) then true else find_dup a tl;;
        
    
    
    let rec app lst2 lst1 =
      match lst1 with
        | [] -> lst2
        | hd::tl -> if (find_dup hd lst2) then (app tl lst2)
         else hd::app tl lst2
         
         
         ;;
    

答案 5 :(得分:-1)

我知道这个问题很旧,但是我找到了一个对我有用的更好的解决方案。也许会对别人有帮助。

因此,确实有可能进行预定的缓存逐出。这是我所做的事情。

@Scheduled和@CacheEvict这两个注释似乎无法一起使用。 因此,您必须将调度方法和缓存逐出方法分开。 但是,由于整个机制都是基于代理的,因此只有对类的公共方法的外部调用才会触发缓存驱逐。这是因为在同一类的方法之间的内部调用不会通过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.
    }    
}