2012-12-18 48 views
9

我正在使用ehcache 2.5.4。基于日期的ehcache

我有一个对象,需要缓存整天,并在每天00:00上午刷新一个新值。

目前使用ehcache配置,我只能设置生存时间和空闲时间,但这取决于我创建对象的时间或使用时间。即:

<cache 
    name="cache.expiry.application.date_status" 
    maxElementsInMemory="10" 
    eternal="false" 
    timeToIdleSeconds="60" 
    timeToLiveSeconds="50" /> 

有没有办法让ehcache根据特定的时间到期特定的缓存。

+2

这不可能直接。如何使用外部CRON触发器([tag:quartz-scheduler]?)手动清除缓存? –

回答

10

我已经通过扩展的Ehcache的Element类像这样做到了这一点:

class EvictOnGivenTimestampElement extends Element { 

    private static final long serialVersionUID = ...; 
    private final long evictOn; 

    EvictOnGivenTimestampElement(final Serializable key, final Serializable value, final long evictOn) { 
     super(key, value); 
     this.evictOn = evictOn; 
    } 

    @Override 
    public boolean isExpired() { 
     return System.currentTimeMillis() > evictOn; 
    } 
} 

其余的是把EvictOnGivenTimestampElement对象的新实例到缓存中,而不是Element一样简单。

这种方法的优点是你不必担心外部cronjob等 而且明显的缺点是附件Ehcache API,我希望不会经常更改。

+0

这似乎是一个非常干净的做法。我可以用注释来做吗?或者我需要手动创建CacheManager。我在Spring和Hibernate中使用它。 – JackDev

+0

'Element'是Ehcache的一个非常基本的概念,并且与'CacheManager'没有直接关系。关于注释 - 我不知道,因为我不使用注释......如果您想在注释中设置不可能被支持的截止日期,但您始终可以按自己想要的方式推出自己的扩展程序。 – mindas

4

EHCache仅在一段时间后支持驱逐(无论是在缓存中还是由于不活动)。但是,你应该能够通过这样的安排去除来实现这一目标相当容易:

Timer t = new Timer(true); 
    Integer interval = 24 * 60 * 60 * 1000; //24 hours 
    Calendar c = Calendar.getInstance(); 
    c.set(Calendar.HOUR, 0); 
    c.set(Calendar.MINUTE, 0); 
    c.set(Calendar.SECOND, 0); 


    t.scheduleAtFixedRate(new TimerTask() { 
      public void run() { 
       Cache c = //retrieve cache     
       c.removeAll();            
      } 
     }, c.getTime(), interval); 

这个基本示例使用了Java定时器类来说明,但可以使用任何计划。每隔24小时,从午夜开始 - 这将运行并从指定的缓存中移除所有元素。实际的run方法可以被修改以移除符合特定标准的元素。

您只需确保在应用程序启动时启动它。

2

随着Ehcache 3.2我实现了Expiry扩展。

public class EvictAtMidnightExpiry implements Expiry { 

    @Override 
    public Duration getExpiryForCreation(Object key, Object value) { 
     DateTime now = new DateTime(); 
     DateTime resetAt = now.plusDays(1).withTimeAtStartOfDay(); 
     long difference = resetAt.toDateTime().getMillis() - now.getMillis(); 
     return Duration.of(difference, TimeUnit.MILLISECONDS); 
    } 

    @Override 
    public Duration getExpiryForAccess(Object key, ValueSupplier value) { 
     return null; 
    } 

    @Override 
    public Duration getExpiryForUpdate(Object key, ValueSupplier oldValue, Object newValue) { 
     return null; 
    } 
} 

现在,我有记录等,但我最小化我的代码清洁。

然后,您只需在配置生成器中对其进行配置即可。

CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, String.class, ResourcePoolsBuilder.heap(1000)).withExpiry(new EvictAtMidnightExpiry()).build() 

显然的Ehcache上有API的有所改善,从2.5到3.2,你不需要创建自己的“元素”,并确保它的使用情况,以发起期满或驱逐政策。这些策略现在缓存绑定。