Spring 缓存抽象 : How to Deal With java. util.Optional<T>

标签 spring hazelcast

我们的代码库中有很多代码类似于以下界面:

public interface SomethingService {
    @Cacheable(value = "singleSomething")
    Optional<Something> fetchSingle(int somethingId);

    // more methods...
}

只要我们只使用本地缓存,这就可以正常工作。但是一旦我们使用像 Hazelcast 这样的分布式缓存,事情就开始崩溃了,因为 java.util.Optional<T>不可序列化,因此无法缓存。

到目前为止我已经提出来解决这个问题:

  1. 删除 java.util.Optional<T>从方法定义中检查可信赖的 null .
  2. 展开 java.util.Optional<T>在缓存实际值之前。

我想避免 (1),因为它会涉及大量重构。而且我不知道如何在不实现我自己的情况下完成 (2) org.springframework.cache.Cache .

我还有哪些其他选择?我更喜欢适用于大多数分布式缓存(Hazelcast、Infinispan 等)的通用(Spring)解决方案,但我也接受仅 Hazelcast 的选项。

最佳答案

一个潜在的解决方案是为 Optional 类型注册一个序列化程序。 Hazelcast 有一个灵活的序列化 API,你可以为任何类型注册一个序列化器。

有关详细信息,请参阅以下示例: https://github.com/hazelcast/hazelcast-code-samples/tree/master/serialization/stream-serializer

所以像这样:

public class OptionalSerializer implements StreamSerializer<Optional> {

@Override
public void write(ObjectDataOutput out, Optional object) throws IOException {
    if(object.isPresent()){
        out.writeObject(object.get());
    }else{
        out.writeObject(null);
    }
}

@Override
public Optional read(ObjectDataInput in) throws IOException {
    Object result = in.readObject();
    return result == null?Optional.empty():Optional.of(result);
}

@Override
public int getTypeId() {
    return 0;//todo:
}

@Override
public void destroy() {

}
}

但是这个解决方案并不完美,因为这个可选的东西将成为实际存储的一部分。所以在内部也存储了 Optional 包装器,这可能会导致问题,例如查询。

关于Spring 缓存抽象 : How to Deal With java. util.Optional<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33474867/

相关文章:

java - 我的 DataSource Bean 做错了什么

spring - 如何检查服务是否实现了grails中的接口(interface)

ehcache - 使用分布式缓存解决方案的开源应用程序

java - 如何获取hazelcast中跨节点分布式映射的内存成本

java - 榛树数据分布

java - Spring MVC - 没有DAO服务层,如何获取当前 session 以进行条件查询

java - Spring集成单元测试http :outbound-gateway

java - 在后端处理 PUT http 请求中的可选字段的最佳方法是什么

tcp - 用于多个网络接口(interface)的 Hazelcast 程序化 TCPIP 配置

java - 从 Hazlcast 缓存获取对象是不可变的