Play 2.6 在Play中使用缓存
使用缓存
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
)
如果你先定义自己的Cached
helper和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;@Injectpublic 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来绑定你的实现。
Play 2.6 在Play中使用缓存相关推荐
- Spring中使用缓存时你应该知道的知识
2019独角兽企业重金招聘Python工程师标准>>> 常见问题 缓存穿透,雪崩,击穿 下面的文章里都有详细介绍 http://blog.csdn.net/zeb_perfect/a ...
- 大型分布式系统中的缓存架构
作者:陈彩华 来自:51cto技术栈(ID:blog51cto) 本文主要介绍大型分布式系统中缓存的相关理论,常见的缓存组件以及应用场景. 缓存概述 缓存概述 缓存的分类 缓存主要分为四类,如下图: ...
- HTTP请求中的缓存(cache)机制
当资源第一次被访问的时候,HTTP头部如下 (Request-Line) GET /a.html HTTP/1.1 Host 127.0.0.1 User-Agent Mozilla/5.0 ...
- Web应用中的缓存一致性问题
2019独角兽企业重金招聘Python工程师标准>>> 上篇总结了缓存中出现频率比较高的一些问题,今天详细说说web应用中的缓存一致性问题. 主要说以下三个方面 数据库与缓存中数据不 ...
- Asp.Net中MVC缓存详解
本文通过介绍了Asp.Net中MVC缓存的种类,以及他们之间的区别等内容,让学习者能够深入的了解MVC缓存的原理机制,以下是具体内容: 缓存是一种保存资源副本并在下次请求时直接使用该副本的技术.当 w ...
- django中的缓存 单页面缓存,局部缓存,全站缓存 跨域问题的解决
django中的缓存 单页面缓存,局部缓存,全站缓存 跨域问题的解决 参考文章: (1)django中的缓存 单页面缓存,局部缓存,全站缓存 跨域问题的解决 (2)https://www.cnblog ...
- web开发中的缓存问题的研究(一)
web开发中的缓存问题的研究(一) web开发中的缓存问题的研究(二) web开发中的缓存问题的研究(三) 一般情况下,浏览器都会缓存已经访问过的页面内容,关于如何禁止浏览器缓存的介绍,在网上到处都有 ...
- Mybatis中的缓存
Mybatis中的缓存 什么是缓存 存在于内存中的临时数据. 为什么使用缓存 减少和数据库的交互次数,提高执行效率. 什么样的数据能使用缓存,什么样的数据不能使用 适用于缓存: 经常查询并且不经常改变 ...
- redis 实际应用中的缓存作用
redis 实际应用中的缓存作用 有人说互联网用户是用脚投票的,这句话其实也从侧面说明了,用户体验是多么的重要:这就要求在软件架构设计时,不但要注重可靠性.安全性.可扩展性以及可维护性等等的一些指标, ...
- 理解分布式系统中的缓存架构(下)
承接上一篇<理解分布式系统中的缓存架构(上)>,介绍了大型分布式系统中缓存的相关理论,常见的缓存组件以及应用场景,本文主要介绍缓存架构设计常见问题以及解决方案,业界案例. 1. 分层缓存架 ...
最新文章
- 【组合数学】递推方程 ( 非齐次部分是指数的情况 | 非齐次部分是指数的情况示例 )
- javascript深入理解js闭包
- 045_Collapse折叠面板
- 文章页点赞php代码,wordpress文章页面添加点赞功能
- 返回值被忽略_《Jenkins Tips 001》 忽略 Shell 步骤中的故障
- qmenu基本用法_使用QProxyStyle定制QMenu (二)
- Java学习笔记-函数
- MySQL/mariadb从删库到跑路——备份
- 算法图解——の——二分查找【附带pdf下载链接】
- redis 使用geo来存储地理经纬度信息
- Android 关于推送通知还需要一些其他的设置问题,最新高频Android笔试题分享
- 我与U盘病毒抗争的那几年——一个特别的进程U盘病毒
- Linux服务器开通443端口
- 程序员上班摸鱼,这么玩才高端!
- Xtrabackup备份与恢复+异机远程流式备份
- 智能工厂建设整体解决方案
- 计算机不能上网 故障分析,电脑不能上网故障排查方法教程
- 电脑配置留底2019.10
- Linux 解压缩文件之zip命令
- 如何不靠运气变得富有 (四) —— 致富与运气无关
热门文章
- 控制类(Controller)
- 多张连续帧图片转为视频,万能转换工具!(Ubuntu系统下亲测有效!)
- TCP 的演化史-sack 与 reordering metric
- 服务网关-Zuul(二)
- imshow函数的替代方案,非常方便
- 【简单】反转双向链表-Java
- linux 中dirname的用法
- mp4文件播放不了怎么办?
- Linux C 编程内存泄露检测工具(二):memwatch
- 【论文笔记】ERNIE-VIL: KNOWLEDGE ENHANCED VISION-LANGUAGE REPRESENTATIONS THROUGH SCENE GRAPH