Schedule Spring cache eviction?

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

If you use @Cacheable on methods with parameters, you should NEVER forget the allEntries=true annotation property on the @CacheEvict, otherwise your call will only evict the key parameter you give to the clearCache() method, which is nothing => you will not evict anything from the cache.


Try to use @Scheduled Example:

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

You can also use cron expression with @Scheduled.


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