Play 2.6 在Play中使用缓存

27 篇文章 2 订阅
1 篇文章 0 订阅

使用缓存

https://playframework.com/documentation/2.6.x/JavaCache

对数据进行缓存是一种很常见的优化方式,Play也提供了全聚德缓存。对于cache有一点很重要,缓存只能做缓存能做的:你刚保存的数据也许会丢失。

对于任何保存在缓存中的数据,当数据丢失时需要一个重新生成的策略。这个哲学存在于Play的基础之中,而且与Java EE不同,session被期待在整个生命周期中保存数据。

Play默认的缓存API是Ehcache

导入缓存API

Play提供了API和默认的Ehcache实现。可以通过以下配置获取完全的Ehcache实现

libraryDependencies ++= Seq(
  ehcache
)

这会在运行时自动进行注入。

如果只想添加API,可以使用如下配置

libraryDependencies ++= Seq(
  cacheApi
)

如果你先定义自己的Cachedhelper和AsynCacheAPI不依赖域Ehcache的绑定,这个API依赖会很有用。如果你使用自己定的缓存模块只能使用这个配置。

JCache的支持

Ehcache支持JSR107标准,也被成为JCache,但是Play默认不绑定javax.caching.CacheManager。为了绑定javax.caching.CacheManager给默认的provider,添加以下配置

libraryDependencies += jcache

如果你使用Guice,可以通过下面的配置来添加Java注解

libraryDependencies += "org.jsr107.ri" % "cache-annotations-ri-guice" % "1.0.0"

获取缓存API

缓存API定义在AsyncCacheAPI和SyncCacheAPI两个接口中,根据你需要同步或者异步的实现,注入到你的类中

import play.cache.*;
import play.mvc.*;

import javax.inject.Inject;

public class Application extends Controller {

    private AsyncCacheApi cache;

    @Inject
    public Application(AsyncCacheApi cache) {
        this.cache = cache;
    }

    // ...
}
Note: The API is intentionally minimal to allow various implementations to be plugged in. If you need a more specific API, use the one provided by your Cache library.

向缓存中写数据

CompletionStage<Done> result = cache.set("item.key", frontPageNews);

也可以设置一个时间(以秒为单位)


// Cache for 15 minutes
CompletionStage<Done> result = cache.set("item.key", frontPageNews, 60 * 15);

读取数据

CompletionStage<News> news = cache.get("item.key");

也可以提供一个Callabel在缓存中数据不存在时生成一个

CompletionStage<News> maybeCached = cache.getOrElseUpdate("item.key", this::lookUpFrontPageNews);

注意:getOrElseUpdate在Ehcache中不是一个原子操作,在实现上先是一个get操作然后是从Callable中计算值最后是set操作。这意味着在多线程的情况下会被计算多次。

删除一个信息

CompletionStage<Done> result = cache.remove("item.key");

清空cache

CompletionStage<Done> resultAll = cache.removeAll();

removeAll()只在异步API中可用,因为很少有情况你需要同步清空cache。只有在一些特殊情况下才需要管理员来清空cache,这不是应用的常规操作。

SyncCacheApi具有相同的API,只是返回值不是用future封装的。

获取不同的缓存

在默认的Ehcache实现中,默认的缓存叫做play,可以通过ehcache.xml进行配置。别的缓存可以使用不同的配置甚至是不同的实现。

如果你需要多种不同的缓存,可以在application.conf中进行绑定

play.cache.bindCaches = ["db-cache", "user-cache", "session-cache"]

默认情况下Play会为你创建这些缓存。如果你想要在ehcache.xml中进行配置,你可以选择

play.cache.createBoundCaches = false

为了在注入时获取不同的缓存,在依赖上使用NamedCache

import play.cache.*;
import play.mvc.*;

import javax.inject.Inject;

public class Application extends Controller {

    @Inject @NamedCache("session-cache") SyncCacheApi cache;

    // ...
}

设定执行上下文

默认情况下Ehcache操作都是阻塞的,异步的实现会阻塞默认执行上下文的线程。

如果你使用Play的默认设置一般情况下不会有问题,只会在内容中存数据所以需要读的尽可能快。

考虑到Ehcache的配置和数据存贮的介质。使用阻塞操作可能太浪费了。

你可以配置一个不同的Akka dispatcher,然后通过play.cache.dispatcher来配置

play.cache.dispatcher = "contexts.blockingCacheDispatcher"

contexts {
  blockingCacheDispatcher {
    fork-join-executor {
      parallelism-factor = 3.0
    }
  }
}

缓存HTTP响应

通过Action组合可以很容易实现

@Cached(key = "homePage")
public Result index() {
    return ok("Hello world");
}

自定义的缓存实现

你可以提供一个自定义的实现来取代或者和默认实现一起使用。

如果要取代默认实现,只需要在build.sbt中添加依赖。如果仍需要Ehcache的实现,可以在application.conf中停用自动绑定

play.modules.disabled += "play.api.cache.ehcache.EhCacheModule"

你可以实现AsyncCacheApi然后绑定到DI容器中。也可以将SyncCacheApi绑定到 DefaultSyncCacheApi中。

注意你的实现不支持removeAll方法,也许是不可能实现也许是不必要。你可以在removeAll方法中抛出一个UnsupportedOperationException 。

为了提供一个缓存API实现,你可以自己创建一个qualifier或者重用NamedCache来绑定你的实现。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值