是否可以将 Spring 缓存驱逐安排在每天的午夜?
我已阅读Springs Cache Docs,但没有发现任何有关计划缓存驱逐的信息。
我需要每天清除缓存并重新缓存它,以防应用程序之外发生一些更改。
尝试使用@Scheduled 示例:
@Scheduled(fixedRate = ONE_DAY)
@CacheEvict(value = { CACHE_NAME })
public void clearCache() {
log.debug("Cache '{}' cleared.", CACHE);
}
您还可以将 cron 表达式与@Scheduled 一起使用。
如果您在带参数的方法上使用@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();
}
}
请按照以下代码操作,相应地更改 cron 表达式。我设置了3分钟
创建一个班级。
在类中使用以下方法。
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());
}
}
我知道这个问题已经很老了,但我找到了一个对我有用的更好的解决方案。也许这会对其他人有所帮助。
因此,确实可以进行计划的缓存驱逐。这是我在我的案例中所做的。
@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.
}
}
将注释 @Scheduled 与 cron 表达式一起使用,将 @CacheEvict 与 allEntries = true 一起使用,如下所示:
/*
* This clears the entire cache called "myCache" everyday,
* at 00.00 (am) in the time zone of the server.
*/
@Scheduled(cron = "0 0 0 * * ?")
@CacheEvict(value = "myCache", allEntries = true)
public void clearMyCache() {}
如果您想在清除缓存之前添加逻辑,您可以在方法主体中执行此操作:
/*
* This clears the entire cache called "myCache" everyday,
* at 00.00 (am) in the time zone of the server.
*/
@Scheduled(cron = "0 0 0 * * ?")
@CacheEvict(value = "myCache", allEntries = true)
public void clearMyCache() {
// Add logic here
log.debug("Clearing myCache now");
}
CacheEvict 会在代码运行后发生,并且仅当它不抛出任何异常时才会发生。您可以通过添加“beforeInspiration = true”来更改它,在这种情况下,它会首先逐出缓存,然后运行您的代码。
Spring 缓存框架是事件驱动的,即
@Cacheable
或 @CacheEvict
仅在调用相应方法时才会触发。
但是,您可以利用底层缓存提供程序(记住 Spring 缓存框架只是一个抽象,本身并不提供缓存解决方案)来自行使缓存失效。例如EhCache有一个属性即。
timeToLiveSeconds
指示缓存处于活动状态之前的时间。但这不会为您重新填充缓存,除非调用 @Cacheable
带注释的方法。
因此,对于特定时间(如上所述的午夜)的缓存驱逐和重新填充,请考虑在 Spring 中实现后台计划服务,这将根据需要触发缓存驱逐和重新填充。未提供开箱即用的预期行为。
希望这有帮助。
您可以定义计划的缓存驱逐,它可以在 cron 表达式上运行。
例如下面的代码将清除缓存
@CacheEvict(value = "movieList", allEntries = true)
@Scheduled(cron = "@midnight", zone = "UTC")
public void evictMoviesCache() {
// Nothing to do. Cache eviction schedule, you can optionally log here.
}
另一种变化是
@CacheEvict(value = "movieList", allEntries = true)
@Scheduled(fixedDelay = 12, timeUnit = TimeUnit.HOURS)
public void evictMoviesCache() {
// Nothing to do. Cache eviction schedule, you can optionally log here.
}