java 计划Spring缓存回收?

zpgglvta  于 2023-05-12  发布在  Java
关注(0)|答案(7)|浏览(186)

有没有可能将 Spring 缓存驱逐安排在每天午夜?
我读了Springs Cache Docs,没有发现任何关于计划缓存回收的内容。
我需要每天清除缓存并重新缓存它,以防在应用程序之外发生了一些更改。

nlejzf6q

nlejzf6q1#

尝试使用@Scheduled示例:

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

你也可以使用cron expression和@Scheduled。

wztqucjr

wztqucjr2#

如果你在带参数的方法上使用@Cacheable,你永远不要忘记@CacheEvict上的allEntries=trueannotation属性,否则你的调用只会驱逐你给予clearCache()方法的关键参数,这是nothing =>你不会从该高速缓存中驱逐任何东西。

rbl8hiat

rbl8hiat3#

也许不是最优雅的解决方案,但@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();
    }
}
628mspwn

628mspwn4#

我知道这个问题很老了,但我找到了一个更好的解决方案。也许这会帮助其他人。
因此,确实可以进行预定的缓存回收。这是我在我的案例中所做的。
注解@Scheduled和@CacheEvict似乎不能一起工作。因此,您必须将调度方法和该高速缓存回收方法分开。但是由于整个机制都是基于代理的,所以只有对类的公共方法的外部调用才会触发该高速缓存回收。这是因为同一个类的方法之间的内部调用不通过Spring代理。
我设法修复了它的方式与西里伯斯(见评论),但与改进,以避免两个组件。

@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.
    }    
}
rbpvctlc

rbpvctlc5#

请按照下面的代码。相应地更改cron表达式。我把它设置为3分钟
1.创建类。
1.在类中使用下面的方法。

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());
    }
}
ckocjqey

ckocjqey6#

Spring Cache框架是事件驱动的,即@Cacheable@CacheEvict仅在调用相应方法时才会被触发。
但是,您可以利用底层缓存提供程序(* 请记住Spring缓存框架只是一个抽象,本身并不提供缓存解决方案 )来使该高速缓存本身无效。例如,EhCache有一个属性,即。timeToLiveSeconds,其指示直到该高速缓存被激活的时间。但这不会为您重新填充该高速缓存,除非调用@Cacheable注解方法。
因此,对于缓存回收和在特定时间重新填充(
如前所述的午夜 *),请考虑在Spring中实现后台调度服务,这将触发该高速缓存回收并根据需要重新填充。预期的行为不是开箱即用的。
希望这能帮上忙。

3pvhb19x

3pvhb19x7#

使用带有cron表达式的注解@Scheduled和带有allEntries = true的注解@CacheEvict,如下所示:

/*
* 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在您的代码运行后发生,并且只有当它没有抛出任何异常时才发生。您可以通过添加“beforeInvocation = true”来更改此设置,在这种情况下,它会首先驱逐该高速缓存,然后运行代码。

相关问题