java 基于日期的缓存

tv6aics1  于 2023-05-15  发布在  Java
关注(0)|答案(4)|浏览(171)

我用的是ehcache 2.5.4。
我有一个对象,需要在一天中缓存,并在每天00:00am刷新一个新值。
目前,在ehcache配置中,我只能设置生存时间和空闲时间,但这取决于我创建对象的时间或使用对象的时间。即:

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

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

gdrx4gfi

gdrx4gfi1#

我通过扩展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放入该高速缓存一样简单。
这种方法的优点是您不必担心外部cronjobs等。明显的缺点是对Ehcache API的附件,我希望它不会经常改变。

a9wyjsp7

a9wyjsp72#

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

这个基本示例使用JavaTimer类进行说明,但也可以使用任何调度程序。每24小时,从午夜开始-这将运行并从指定的缓存中删除所有元素。实际的run方法也可以修改为删除符合特定条件的元素。
您只需要确保在应用程序启动时启动它。

watbbzwu

watbbzwu3#

在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,因为你不需要创建自己的“元素”,并确保它的使用启动到期或驱逐政策。这些策略现在是缓存绑定的。

wsewodh2

wsewodh24#

使用LocalTime实现ehcache 3.8,无需额外的库:

import java.time.Duration;
import java.time.LocalTime;
import java.util.function.Supplier;
import org.ehcache.expiry.ExpiryPolicy;

/**
 * XML configuration example:
 * <pre>
 *   {@code
 *   <cache alias="...
 *     <expiry>
 *       <class>org.example.MidnightExpiry</class>
 *     </expiry>
 *   </cache>
 *   }
 * </pre>
 */
public class MidnightExpiry implements ExpiryPolicy<Object, Object> {

  private static final LocalTime MIDNIGHT = LocalTime.of(23, 59, 59, 999999999);

  @Override
  public Duration getExpiryForCreation(Object key, Object value) {
    return Duration.between(LocalTime.now(), MIDNIGHT);
  }
  
  @Override
  public Duration getExpiryForAccess(Object key, Supplier value) {
    // do not change expiry on access
    return null;
  }

  @Override
  public Duration getExpiryForUpdate(Object key, Supplier oldValue, Object newValue) {
    // do not change expiry on update
    return null;
  }
}

相关问题