为什么guava缓存只能在本地缓存中存储非null值以及如何绕过它

时间:2013-08-27 11:16:00

标签: java caching guava ehcache

我正在使用google的guava utils将本地缓存添加到我的服务器。

guava非常适合我的场景,除了它只能将“非空”值存储到其本地缓存中(com.google.common.cache.Cache和com.google.common.cache.LoadingCache都这样做)。

嗯,这不好。因为我的服务器可能无法从远程数据库获取值,因为时间用完或其他原因。如果我给guava一个默认值,它将被存储在本地缓存中,并且将始终存在,除非满足某些驱逐条件。但问题是我不能给番石榴一个合理的默认值。

有人可以告诉我,为什么番石榴有这个限制,我怎么能绕过它呢? ehcache可以更适合我的情况吗?

4 个答案:

答案 0 :(得分:5)

番石榴并不是真正无效的。我邀请你阅读关于null [1]的宣言。

如果您必须绕过该行为,请使用Optional<V> [2]。因此,不要使用LoadingCache<K, V>CacheLoader<K, V>,而是使用LoadingCache<K, Optional<V>>CacheLoader<Optional<V>>

通过这种方式,您可以继续使用Cache的强大功能并添加灵活性Optional优惠。

  1. http://code.google.com/p/guava-libraries/wiki/UsingAndAvoidingNullExplained
  2. http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/base/Optional.html

答案 1 :(得分:1)

您可以使用Null对象设计模式http://en.wikipedia.org/wiki/Null_Object_pattern

答案 2 :(得分:1)

如果你只是试图从远程数据库中获取值,是否真的想要缓存null(或任何代表“缺席”的东西)?您可以抛出异常,这将指示获取值的失败(而不是刚刚存在的值)并且也没有向缓存添加任何内容,因此当您尝试再次获取密钥的值时它会尝试再次从数据库中读取。

答案 3 :(得分:0)

在ehcache中,您可以区分空值和不存在的键,但是您需要额外的Element类。

// ehcache
cache.put(new Element("key1", null));
assertNull(cache.get("key1").getObjectValue());  // null value
assertNull(cache.get("key2"));  // key is not exist

在番石榴中,您不必使用额外的类,但无法区分空值和不存在的键。

// plain guava
cache.put("key1", "value1");
assertNull(cache.getIfPresent("key2"));  // key is not exist

正如其他人所说,你可以使用空对象模式或Optional与番石榴。有了这样一个额外的类,你可以像ehcache一样处理null值。

// guava with Optional
cache.put("key1", Optional.absent());
assertFalse(cache.getIfPresent("key1").isPresent());  // null value
assertNull(cache.getIfPresent("key2"));  // key is not exist