我是否可以像cron作业一样,将javaspring缓存安排在每小时的顶部过期?

8e2ybdfx  于 2021-07-23  发布在  Java
关注(0)|答案(2)|浏览(303)

我把它设置为12小时后过期。但是,它也会在每个缓存首次写入后12小时过期。我只想在早上12点和晚上12点刷新。这可能吗?在我的cacheconfig文件中,我有:

@Component
@EnableCaching
public class CacheConfig {

   @Bean
   public Caffeine defaultCacheConfig() {
       return Caffeine.newBuilder()
               .expireAfterWrite(12, TimeUnit.HOURS);
   }
}

我正在使用缓存库。

ykejflvf

ykejflvf1#

咖啡因支持可变过期,其中条目的持续时间必须独立计算。如果您希望所有条目同时过期,您可以编写,

Caffeine.newBuilder()
    .expireAfter(new Expiry<K, V>() {
      public long expireAfterCreate(K key, V value, long currentTime) {
        var toMidnight = Duration.between(LocalDate.now(), 
            LocalDate.now().plusDays(1).atStartOfDay());
        var toNoon = Duration.between(LocalTime.now(), LocalTime.NOON);
        return toNoon.isNegative() ? toMidnight.toNanos() : toNoon.toNanos();
      }
      public long expireAfterUpdate(K key, V value, 
          long currentTime, long currentDuration) {
        return currentDuration;
      }
      public long expireAfterRead(K key, V value, 
          long currentTime, long currentDuration) {
        return currentDuration;
      }
    }).build();

对于这样一个简单的任务来说,使用expiration可能有点过头了。相反,如果您想清除缓存,那么一个计划任务可以这样做,正如@alexzander zharkov所建议的那样。

@Scheduled(cron = "0 0,12 * * *")
public void clear() {
  cache.invalidateAll();
}

由于这会清空缓存,因此在重新加载条目时会有性能损失。相反,您可以异步刷新缓存,以便在不惩罚任何调用者的情况下重新加载条目。

@Scheduled(cron = "0 0,12 * * *")
public void refresh() {
  cache.refreshAll(cache.asMap().keySet());
}
euoag5mw

euoag5mw2#

我相信咖啡因不支持这种安排。但是如果这是一个很强的需求,并且应该按如下方式实现-您可以使用spring的@scheduled注解,它允许使用cron config。您可以在这里阅读:https://www.baeldung.com/spring-scheduled-tasks
因此,对于我的愿景,它可以通过以下方式工作:
设置计划的spring服务并配置所需的cron。通过字段或构造函数自动连接cachemanager,并设置refreshcache()以清除cachemanager的所有缓存。我将留下一个代码示例,但不确定它是否100%有效:)

@Component
  public class CacheRefreshService {

     @Autowired
     private CacheManager cacheManager;

     @Scheduled(cron = ...)
     public void refreshCache() {
        cacheManager.getCacheNames().stream()
           .map(CacheManager::getCache)
           .filter(Objects::nonNull)
           .forEach(cache -> cache.clear());
     }
 }

别忘了为@configuration-s设置@enablescheduling,如果您正在运行@springbootplication,也可以将它添加到@springbootplication。

相关问题