首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >EhCache磁盘持久化-持久化任意对象

EhCache磁盘持久化-持久化任意对象
EN

Stack Overflow用户
提问于 2017-08-14 02:22:25
回答 1查看 954关注 0票数 0

我想使用EhCache来持久化磁盘上的对象,所以在下次运行我的应用程序时,它将从它加载。在他们的文档中,有以下使用PersistentCacheManager类执行此操作的示例:

代码语言:javascript
复制
PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder().with(CacheManagerBuilder.persistence(new File(getStoragePath(), "myData"))).withCache("persistent-cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class,
ResourcePoolsBuilder.newResourcePoolsBuilder().disk(10, MemoryUnit.MB, true))).build(true);
persistentCacheManager.close();

这个示例运行得很好,但是如果CacheConfigurationBuilder对象定义了键和值的类,将它们硬编码为Long和String,对我来说就是问题。我希望持久化任意类的实例,而不是预定义哪些类。此外,CacheConfigurationBuilder不会以Object.class或HashMap.class为例。

如何使用EhCache在磁盘上持久化任意实例类?

EN

回答 1

Stack Overflow用户

发布于 2017-08-14 07:26:10

Ehcache可以接受任何键或值。默认情况下,它要求它们必须是可序列化的。否则,它无法知道如何将其存储在堆外或磁盘上。

HashMap是可序列化的,因此您不会从它得到警告。Map并非如此。所以你会得到一个警告,但如果实现实际上是可序列化的,它仍然可以工作。

然而,如果你真的存储了一个不可序列化的对象,你确实会得到一个异常。解决方案是指定一个键和/或一个值序列化程序,告诉Ehcache如何存储您想要的任何内容。完整的文档是there

现在让我们看一个例子。您有一个要缓存的类MyClass

代码语言:javascript
复制
public class MyClass {
  private String value;

  public MyClass(String value) {
    this.value = value;
  }

  public String getValue() {
    return value;
  }

  @Override
  public boolean equals(Object o) {
    if(this == o) { return true; }
    if(o == null || getClass() != o.getClass()) { return false; }
    MyClass myClass = (MyClass) o;
    return Objects.equals(value, myClass.value);
  }

  @Override
  public int hashCode() {
    return value != null ? value.hashCode() : 0;
  }
}

并进行测试以确保其正常工作。

代码语言:javascript
复制
@Test
public void test() {
  try(CacheManager persistentCacheManager =
        newCacheManagerBuilder()
          .withCache("test-cache",
            newCacheConfigurationBuilder(Integer.class, MyClass.class,
              newResourcePoolsBuilder().offheap(1, MemoryUnit.MB)))
          .withSerializer(MyClass.class, MySerializer.class)
          .build(true)) {

    Cache<Integer, MyClass> cache = persistentCacheManager.getCache("test-cache", Integer.class, MyClass.class);
    cache.put(1, new MyClass("test"));
    MyClass actual = cache.get(1);
    assertEquals("test", actual.getValue());
  }

}

您的序列化程序将如下所示:

代码语言:javascript
复制
public class MySerializer implements Serializer<MyClass> {

  public MySerializer(ClassLoader unused) {
  }

  @Override
  public ByteBuffer serialize(MyClass object) throws SerializerException {
    try(ByteArrayOutputStream bout = new ByteArrayOutputStream(); ObjectOutputStream oout = new ObjectOutputStream(bout)) {
      oout.writeUTF(object.getValue());
      oout.flush();
      return ByteBuffer.wrap(bout.toByteArray());
    } catch (IOException e) {
      throw new SerializerException(e);
    }
  }

  @Override
  public MyClass read(ByteBuffer binary) throws ClassNotFoundException, SerializerException {
    try(ObjectInputStream oin = new ObjectInputStream(new ByteBufferInputStream(binary))) {
        return new MyClass(oin.readUTF());
    } catch (IOException e) {
      throw new SerializerException(e);
    }
  }

  @Override
  public boolean equals(MyClass object, ByteBuffer binary) throws ClassNotFoundException, SerializerException {
    return object.equals(read(binary));
  }

}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45663526

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档