2012-12-18 47 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,你不需要創建自己的「元素」,並確保它的使用情況,以發起期滿或驅逐政策。這些策略現在緩存綁定。