我认为您必须区分缓存库和访问它的 API。我见过的在 Scala 环境中使用的缓存库与在 Java 环境中使用的缓存库相同。对于(可能)分布式缓存,使用 Ehcache 或 memcached 之类的东西。对于本地缓存,通常使用 guava 库的缓存实用程序。
为本地缓存 API 编写一个包装器是很容易的,以便有一种更符合 scala 习惯的方式来访问缓存。您在示例中使用的注解是访问 Java 中库抽象的常用方法,但在 Scala 世界中并不常见。表演!例如,框架有一个缓存抽象,默认情况下,它绑定到 Ehcache。它允许以下构造:
val user: User = Cache.getOrElseAs[User]("item.key") {
User.findById(connectedUser)
}
Twitter 在他们的 scala 实用程序中有一个 guava 缓存的包装器,但删除了它们。我认为是这样,因为在当前的番石榴版本中,直接访问它非常简单/实用。
val cache =
CacheBuilder.newBuilder().
maximumSize(1000).
build((key:String) => q(key))
例如,如果您在范围内有以下隐式转换,这将正常工作:
implicit def functionToCacheLoader[F, T](f: F => T) = {
new CacheLoader[F, T] {
def load(key: F) = f(key)
}
}
最后,向番石榴缓存本身添加一些糖也很容易:
implicit def pimpCache[F, T](cache: Cache[F, T]) = {
new PimpedCache(cache)
}
class PimpedCache[F, T](cache: Cache[F, T]) {
def getOption(key: F) = {
val value = cache.getIfPresent(key)
if(value == null) None else Some(value)
}
}
这些是我使用的缓存的主要抽象。这是一个包含我需要的所有代码的要点的链接。我也有一个播放插件!缓存抽象,它在引擎盖下使用番石榴,如果您需要使用它,我可以分享。