简体   繁体   中英

Schedule Spring cache eviction?

Is it possible to schedule spring cache eviction to everyday at midnight?

I've read Springs Cache Docs and found nothing about scheduled cache eviction.

I need to evict cache daily and recache it in case there were some changes outside my application.

Try to use @Scheduled Example:

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

You can also use cron expression with @Scheduled.

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

I know this question is old, but I found a better solution that worked for me. Maybe that will help others.

So, it is indeed possible to make a scheduled cache eviction. Here is what I did in my case.

Both annotations @Scheduled and @CacheEvict do not seem to work together. You must thus split apart the scheduling method and the cache eviction method. But since the whole mechanism is based on proxies, only external calls to public methods of your class will trigger the cache eviction. This because internal calls between to methods of the same class do not go through the Spring proxy.

I managed to fixed it the same way as Celebes (see comments), but with an improvement to avoid two components.

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

Maybe not the most elegant solution, but @CacheEvict was not working, so I directly went for the CacheManager .

This code clears a cache called foo via scheduler:

class MyClass {

    @Autowired CacheManager cacheManager;

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

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

Spring cache framework is event driven ie @Cacheable or @CacheEvict will be triggered only when respective methods are invoked.

However you can leverage the underlying cache provider ( remember the Spring cache framework is just an abstraction and does not provide a cache solution by itself ) to invalidate the cache by itself. For instance EhCache has a property viz. timeToLiveSeconds which dictates the time till the cache be active. But this won't re-populate the cache for you unless the @Cacheable annotated method is invoked.

So for cache eviction and re-population at particular time ( say midnight as mentioned ) consider implementing a background scheduled service in Spring which will trigger the cache eviction and re-population as desired. The expected behavior is not provided out-of-box.

Hope this helps.

Please follow the below code.change cron expression accordingly. I have set it for 3 minutes

  1. Create a class.

  2. Use the below method inside the 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()); } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM