java将对象 缓存_ehcache java 对象缓存怎么实现

展开全部

1.技术背景:

系统缓存是32313133353236313431303231363533e4b893e5b19e31333337396236位于应用程序与物理数据源之间,用于临时存放复制数据的内存区域,目的是为减少应用程序对物理数据源访问的次数,从而提高应用程序的运行性能。缓存设想内存是有限的,缓存的时效性也是有限的,所以可以设定内存数量的大小可以执行失效算法,可以在内存满了的情况下,按照最少访问等算法将缓存直接移除或切换到硬盘上。

Ehcache从Hibernate发展而来,逐渐涵盖了Cache界的全部功能,是目前发展势头最好的一个项目,具有快速、简单、低消耗、扩展性强、支持对象或序列化缓存,支持缓存或元素的失效,提供LRU、LFU和FIFO缓存策略,支持内存缓存和硬盘缓存和分布式缓存机制等特点。其中Cache的存储方式为内存或磁盘(ps:无须担心容量问题)

2.EhCahe的类层次介绍:

主要分为三层,最上层是CacheManager,它是操作Ehcache的入口。可以通过CacheManager.getInstance()获得一个单子的CacheManager,或者通过CacheManager的构造函数创建一个新的CacheManager。每个CacheManger都管理多个Cache。每个Cache都以一种类Hash的方式,关联多个Element。Element就是我们用于存放缓存内容的地方。

3.环境搭建:

很简单只需要将ehcache-2.1.0-distribution.tar.gz和ehcache-web-2.0.2-distribution.tar.gz挤压的jar包放入WEB-INF/lib下。

再创建一个重要的配置文件ehcache.xml,可以从ehcache组件包中拷贝一个,也可以自己建立一个,需要放到classpath下,一般放于/WEB-INF/classed/ehcache.xml;具体的配置文件可以网上搜一下

4.实际运用

一个网站的首页估计是被访问次数最多的,我们可以考虑给首页做一个页面缓存;

缓存策略:应该是某个固定时间之内不变的,比如说2分钟更新一次,以应用结构page-filter-action-service-dao-db为例。

位置:页面缓存做到尽量靠近客户的地方,就是在page和filter之间,这样的优点就是第一个用户请求后,页面被缓存,第二个用户在请求,走到filter这个请求就结束了,需要在走到action-service-dao-db,好处当然是服务器压力大大降低和客户端页面响应速度加快。

首页页面缓存存活时间定为2分钟,也就是参数timeToLiveSeconds(缓存的存活时间)应该设置为120,同时timeToIdleSeconds(多长时间不访问缓存,就清楚该缓存)最好也设为2分钟或者小于2分钟。



接着我们来看一下SimplePageCachingFilter 的配置,

indexCacheFilterfilter-name>

net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter

indexCacheFilterfilter-name>

*index.actionurl-pattern>

将上述代码加入到web.xml,那么当打开首页时,你会发现2分钟才会有一堆sql语句出现在控制台,也可以调整为5分钟,总之一切尽在掌控之中。

当然,如果你像缓存首页的部分内容时,你需要使用SimplePageFragmentCachingFilter这个filter,我看一下:

indexCacheFilterfilter-name>

net.sf.ehcache.constructs.web.filter.SimplePageFragmentCachingFilter

filter>

indexCacheFilterfilter-name>

*/index_right.jsp

如此我们将jsp页面通过jsp:include到其他页面,这样就做到了页面局部缓存的效果,这一点貌似没有oscache的tag好用。

此外cachefilter中还有一个特性,就是gzip,也就是缓存中的元素是被压缩过的,如果客户端浏览器支持压缩的话,filter会直接返回压缩过的流,这样节省了带宽,把解压的工作交给了客户端浏览即可,当然如果客户端不支持gzip,那么filter会把缓存的元素拿出来解压后在返回给客户端浏览器(大多数爬虫是不支持gzip的,所以filter也会解压后在返回流)。

总之,Ehcache是一个非常轻量级的缓存实现,而且从1.2之后支持了集群,而且是hibernate默认的缓存provider,本文主要介绍Ehcahe对页面缓存的支持,但是它的功能远不止如此,要用好缓存,对J2ee中缓存的原理、适用范围、适用场景等等都需要比较深刻的理解,这样才能用好用对缓存。

为了大家通过实际例子加深了解与场景运用,在奉献一个实例:

*在Spring中运用EhCache

适用任意一个现有开源Cache Framework,要求可以Cache系统中service或者DAO层的get/find等方法返回结果,如果数据更新(适用了Create/update/delete),则刷新cache中相应的内容。

根据需求,计划适用Spring AOP+enCache来实现这个功能,采用ehCache原因之一就是Spring提供了enCache的支持,至于为何仅仅支持ehcache而不支持oscache和jbosscache就无从得知了。

AOP少不了拦截器,先创建一个实现了MethodInterceptor接口的拦截器,用来拦截Service/DAO的方法调用,拦截到方法后,搜索该方法的结果在cache中是否存在,如果存在,返回cache中结果,如果不存在返回数据库查询结果,并将结果返回到缓存。

public class MethodCacheInterceptor implements MethodInterceptor, InitializingBean

{

private static final Log logger = LogFactory.getLog(MethodCacheInterceptor.class);

private Cache cache;

public void setCache(Cache cache) {

this.cache = cache;

}

public MethodCacheInterceptor() {

super();

}

/**

* 拦截Service/DAO 的方法,并查找该结果是否存在,如果存在就返回cache 中的值,

* 否则,返回数据库查询结果,并将查询结果放入cache

*/

public Object invoke(MethodInvocation invocation) throws Throwable {

String targetName = invocation.getThis().getClass().getName();

String methodName = invocation.getMethod().getName();

Object[] arguments = invocation.getArguments();

Object result;

logger.debug("Find object from cache is " + cache.getName());

String cacheKey = getCacheKey(targetName, methodName, arguments);

Element element = cache.get(cacheKey);

Page 13 of 26

if (element == null) {

logger.debug("Hold up method , Get method result and create cache........!");

result = invocation.proceed();

element = new Element(cacheKey, (Serializable) result);

cache.put(element);

}

return element.getValue();

}

/**

* 获得cache key 的方法,cache key 是Cache 中一个Element 的唯一标识

* cache key 包括包名+类名+方法名,如com.co.cache.service.UserServiceImpl.getAllUser

*/

private String getCacheKey(String targetName, String methodName, Object[] arguments) {

StringBuffer sb = new StringBuffer();

sb.append(targetName).append(".").append(methodName);

if ((arguments != null) && (arguments.length != 0)) {

for (int i = 0; i 

sb.append(".").append(arguments[i]);

}

}

return sb.toString();

}

/**

* implement InitializingBean,检查cache 是否为空

*/

public void afterPropertiesSet() throws Exception {

Assert.notNull(cache, "Need a cache. Please use setCache(Cache) create it.");

}

}

上面的代码可以看到,在方法invoke中,完成了搜索cache/新建cache的功能

随后,再建立一个拦截器MethodCacheAfterAdvice,作用是在用户进行create/update/delete操作时来刷新、remove相关cache内容,这个拦截器需要实现AfterRetruningAdvice接口,将会在所拦截的方法执行后执行在afterReturning(object arg0,Method arg1,Object[] arg2,object arg3)方法中所预定的操作

public class MethodCacheAfterAdvice implements AfterReturningAdvice, InitializingBean

{

private static final Log logger = LogFactory.getLog(MethodCacheAfterAdvice.class);

private Cache cache;

Page 15 of 26

public void setCache(Cache cache) {

this.cache = cache;

}

public MethodCacheAfterAdvice() {

super();

}

public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws

Throwable {

String className = arg3.getClass().getName();

List list = cache.getKeys();

for(int i = 0;i

String cacheKey = String.valueOf(list.get(i));

if(cacheKey.startsWith(className)){

cache.remove(cacheKey);

logger.debug("remove cache " + cacheKey);

}

}

}

public void afterPropertiesSet() throws Exception {

Assert.notNull(cache, "Need a cache. Please use setCache(Cache) create it.");

}

}

该方法获取目标class的全名,如:com.co.cache.test.TestServiceImpl,然后循环cache的key list,刷新/remove cache中所有和该class相关的element。

接着就是配置encache的属性,如最大缓存数量、cache刷新的时间等等。

maxElementsInMemory="1000"

eternal="false"

timeToIdleSeconds="120"

timeToLiveSeconds="120"

overflowToDisk="true"

/>

maxElementsInMemory="10000"

eternal="false"

timeToIdleSeconds="300000"

timeToLiveSeconds="600000"

overflowToDisk="true"

/>

这里需要注意的是defaultCache定义了一个默认的cache,这个Cache不能删除,否则会抛出No default cache is configured异常。另外由于使用拦截器来刷新Cache内容,因此在定义cache生命周期时可以定义较大的数值,timeToIdleSeconds="30000000",timeToLiveSeconds="6000000",好像还不够大?

然后再将Cache和两个拦截器配置到Spring的配置文件cache.xml中即可,需要创建两个“切入点”,分别用于拦截不同方法名的方法。在配置application.xml并且导入cache.xml。这样一个简单的Spring+Encache框架就搭建完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

语义分割和实例分割_一文读懂语义分割与实例分割

以人工智能为导向的现代计算机视觉技术,在过去的十年中发生了巨大的变化。今天,它被广泛用于图像分类、人脸识别、物体检测、视频分析以及机器人及自动驾驶汽车中的图像处理等领域。图像分割技术是目前预测图像领域最热门的一项技术,原因在于…

游戏自审自查报告_开发的射箭小游戏上线了,分享一下我在开发过程中遇到的问题...

利用业余时间开发的微信小游戏-射箭救人质上线了,主要玩法就是操作弓箭射断绳子把人救下来就可以了。图片资源是我找一个朋友做的。开发过程不算太顺利。磕磕绊绊做了12关。希望大家支持下。谢谢。分享一下我在开发中遇到的问题和部分解决方案、希望对大家有所帮助。…

java float 存储方式_java-解析以字符串形式存储的float会抛出异...

在相关的源代码中可以看到,该值将被修剪:static FloatingDecimal.ASCIIToBinaryConverter readJavaFormatString(String arg) throws NumberFormatException {boolean arg0 false;boolean arg1 false;try {arg arg.trim();....因此,在转换为floatValue之前将删除…

java 抛出异常的目的_Java实验八,异常

一.实验目的1. 掌握自定义异常类的编写;2. 掌握使用try-catch语句来处理异常。二.实验内容及要求车站检查危险品的设备,如果发现危险品会发出警告。编程模拟设备发现危险品:1. 编写一个Exception的子类DangerException,该子类可以…

pythongui显示图片_opencv2.4.13+python2.7学习笔记--opencv中的Gui特性--图片:读图像,显示图像,保存图像...

#-*- coding: utf-8 -*-"""Created on Tue Mar 14 19:39:11 2017author: Thinkpad"""2.opencv中的Gui特性2.1图片:读图像,显示图像,保存图像读图像cv2.imread(a,b)a:图像所在的路径b:如何读取图片cv2.IMREAD_C…

postmapping注解_Swagger常用注解

在使用swagger时候如果掌握一些注解的使用,则在开发过程中测试的时候可以事半功倍,尤其在与前端技术进行联调,前端技术在访问swagger中的每个api时,可以很清楚的知道每个url对应的请求类型、参数类型、参数是否非必输、参数个数等…

java map 多个值_java 一个函数EnumMap返回多个值

在开发过程中,经常会有这种情况,就是一个函数需要返回多个值,这是一个问题!!网上这个问题的解决方法:1、使用map返回值;这个方法问题是,你并不知道如何返回值的key是什么&#xff0c…

python pandas 日期_python+pandas+时间、日期以及时间序列处理方法

pythonpandas时间、日期以及时间序列处理方法先简单的了解下日期和时间数据类型及工具 python标准库包含于日期(date)和时间(time)数据的数据类型,datetime、time以及calendar模块会被经常用到。 datetime以毫秒形式存储日期和时间,datetime.timedelta表…

java程序怎么都不是一个_java运行的流程-怎么运行java程序编了一个程序不知道怎么运行郁闷啊后缀文件名是 爱问知识人...

在初学java编程语言时,痛苦的事莫过于跟着示例一步步做,总是得不到想要的结果,这是很多初学者都会碰到的问题。下面详细教你运行第一个java应用程序(环境windows xp jdk 6。0):第一步:下载并安装JDK 6。0,…

调用别的方法的返回值_Spring boot如何实现异步调用

Spring boot如何实现异步调用异步调用:一个可以无需等待被调用函数的返回值就让操作继续进行的方法举个例子异步调用就是你 喊 你朋友吃饭 ,你朋友说知道了 ,待会忙完去找你 ,你就去做别的了。同步调用就是你 喊 你朋友吃饭 ,你朋…

java excel 创建按钮_通过单击Excel按钮在Catia中设计零件

我已经在用宏编辑器构建的Catia V5中编写了一些宏,但我无法弄清楚如何从Excel访问Catia命令 .我想知道如何通过仅在excel文件圆柱体的半径和长度中创建一个简单的直圆柱体 .我想在Catia中输入不同的压力容器,在Excel中输入它们的直径和高度,然…

pythonspot_python-Spotipy-列表索引超出范围

编写Spotipy脚本以从给定专辑返回专辑曲目,我偶尔会遇到错误:album_id results["albums"]["items"][0]["uri"]IndexError: list index out of range这种错误往往发生在更多的流行歌手遍历所有专辑的时候.我猜结果列表已达到极限或以…

国防科大JAVA工程师笔试题_国防科大人工智能考博题答案

【实例简介】国防科大计算机学院考博试题 人工智能11-15年试题答案A-20年33(注主:图21的日2该是想反3):61(35),610)①到日1①bs15②①9-519海:S→B>D>印k0b4763到句2(013-13e(as|0⊙(升早巧一③Cm52B877③1315④①a3s93(62833106舞决:5>B→>D>2或5A>C>D→…

python四舍五入保留小数点后三位_Python中的“正确”四舍五入到小数点后3位

我可能遗漏了一些重要的东西,但我无法找到一种方法来在Python(2.7)中将浮点/小数“适当”舍入,至少舍入到小数点后三位。我的意思是1.2225应该四舍五入到1.223,而1.2224应该四舍五入到1.222。在我知道在Python中,round不适用于flo…

java 指代对象_java-This的理解

都知道this是一个指代作用吧,但指代的是什么?一般网上搜索的this 都说是“当前对象”,但这样说和没说区别一个样,什么是“当前对象”都说不清楚。但其实,this指代得分下面4种情况来说。有的是场景展示的(如一、三)&…

python 日历查询系统_python 日历

上章总结了python中time模块的使用,这次总结日历模块 calendar>>> import calendar>>> cal calendar.month(2016,1)>>> calJanuary 2016\nMo Tu We Th Fr Sa Su\n 1 2 3\n 4 5 6 7 8 9 10\n11 12 13 14 15 16 17\n1…

在java语法中继承_java中的继承

一、继承:1.如果不使用继承,会出现以下一些问题:(1)代码重复(2)如果要修改的话,两个类都需要修改。2.继承体现的是一种is a 的关系。eg:Dog is a Pet;apple is a Fruit;Student is a Person;二、子类可以继承到父类的哪些财产呢&a…

照片识别出错_AI跨年龄人脸识别技术在跨年龄寻亲的应用简析

9月3日,央视财经《经济半小时》栏目播出了一段有关失踪儿童找回的视频新闻。在这则新闻中,跨年龄人脸识别技术是最为核心的功臣,深圳警方利用跨年龄人脸识别技术,根据一张3岁孩童的儿童照片找回了失踪了十几年的孩子,让…

python内置的数字运算函数_Python 内置函数1

abs(x)函数返回绝对值参数可以是&#xff1a;负数、正数、浮点数或者长整形print(abs(-1.2))# 结果1.2cmp(x, y)函数 (python3已删)中文说明&#xff1a;比较两个对象x和y&#xff0c;如果x < y ,返回负数&#xff1b;x y, 返回0&#xff1b;x > y,返回正数。版本&#…

java音频采样_音频重采样的坑

背景使用webrtc进行语音通话&#xff0c;网络正常的情况下&#xff0c;延迟比较大。进行过如下分析&#xff1a;(1)从socket收包到webrtc处理完音频没有耗时长的操作&#xff0c;排除了webrtc处理音频引入的延迟(2)与其他终端进行通话无延迟通过以上的分析&#xff0c;最终确认…