如何在Spring Boot中清除所有缓存?

25
在应用启动时,我初始化了大约20个不同的缓存:
@Bean
public CacheManager cacheManager() {
    SimpleCacheManager cacheManager = new SimpleCacheManager();
    cacheManager.setCaches(Arrays.asList(many many names));
    return cacheManager;
}

我希望定时清除所有缓存,比如每个小时。使用一个预定任务:

@Component
public class ClearCacheTask {

    private static final Logger logger = LoggerFactory.getLogger(ClearCacheTask.class);
    private static final DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd hh:mm:ss");

    @Value("${clear.all.cache.flag}")
    private String clearAllCache;

    private CacheManager cacheManager;

    @CacheEvict(allEntries = true, value="...............")
    @Scheduled(fixedRate = 3600000, initialDelay = 3600000) // reset cache every hr, with delay of 1hr
    public void reportCurrentTime() {
        if (Boolean.valueOf(clearAllCache)) {
            logger.info("Clearing all cache, time: " + formatter.print(DateTime.now()));
        }
    }
}

除非我误解了文档,但是@CacheEvict需要我实际提供缓存的名称,这可能会很麻烦。

我该如何使用@CacheEvict来清除所有缓存?

我在考虑,是否可以不使用@CacheEvict,而是遍历所有缓存:

cacheManager.getCacheNames().parallelStream().forEach(name -> cacheManager.getCache(name).clear());

3
为什么不使用像 ehcache 这样的适当缓存实现,而是要将一些东西拼凑在一起呢?通过简单配置缓存就能支持这种操作。 - M. Deinum
我应该添加免责声明:是的,这很愚蠢/粗糙,但必须这样做。 - iCodeLikeImDrunk
我会选择选项2,不要尝试使用@CacheEvict,因为它并不是为此而设计的,但它仍然是一种hack方法,你应该使用适当的缓存技术。 - M. Deinum
2个回答

63

我刚刚使用了定时任务,利用缓存管理器清除了所有缓存。

@Component
public class ClearCacheTask {
    @Autowired
    private CacheManager cacheManager;

    @Scheduled(fixedRateString = "${clear.all.cache.fixed.rate}", initialDelayString = "${clear.all.cache.init.delay}") // reset cache every hr, with delay of 1hr after app start
    public void reportCurrentTime() {
        cacheManager.getCacheNames().parallelStream().forEach(name -> cacheManager.getCache(name).clear());
    }
}

完成工作。


5
对于所有初次使用Spring Boot进行调度的人:不要忘记在您的Spring Boot应用程序类中添加@EnableScheduling注解。(您应该已经拥有@SpringBootApplication@EnableCaching注解。) - Datz

3
以下evictCache方法使用@CacheEvict注释来清除fooCache。
public class FooService {

  @Autowired 
  private FooRespository repository;

  @Cacheable("fooCache")
  public List<Foo> findAll() {
    return repository.findAll();
  }

  @CacheEvict(value="fooCache",allEntries=true)
  public void evictCache() {
    LogUtil.log("Evicting all entries from fooCache.");
  }
}

但是什么时候会执行呢?你需要安排计划或者其他什么吗,对吧? - Carlos López Marí
这完全与 OP 所要求的相反。如果除了 fooCache 之外还有其他 20 种类型的缓存,则无法使用 @CacheEvict。 - saran3h

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接