Java缓存组件 EhCache 入门教程

1.技术背景:

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

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 的配置,

<filter>
<filter-name>indexCacheFilterfilter-name>
<filter-class>
net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter
<filter-class>
<filter>
<filter-mapping>
<filter-name>indexCacheFilterfilter-name>
<url-pattern>*index.actionurl-pattern>
<filter-mapping>

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

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

<filter>
<filter-name>indexCacheFilterfilter-name>
<filter-class>
net.sf.ehcache.constructs.web.filter.SimplePageFragmentCachingFilter
<filter-class>
filter>
<filter-mapping>
<filter-name>indexCacheFilterfilter-name>
<url-pattern>*/index_right.jsp<url-pattern>
<filter-mapping>

如此我们将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 < arguments.length; 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<list.size();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刷新的时间等等。

<ehcache>
<diskStore path="c:\\myapp\\cache"/>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
<cache name="DEFAULT_CACHE"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300000"
timeToLiveSeconds="600000"
overflowToDisk="true"
/>
</ehcache>

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

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

由于时间关系就介绍到这里,以后有机会还会介绍Ehcache在分布式集群系统中的使用,谢谢大家。
转自:http://blog.csdn.net/yangchao228/article/details/7027485

时间: 2024-10-01 11:36:13

Java缓存组件 EhCache 入门教程的相关文章

缓存系列-Redis入门教程

Redis是什么? Redis (REmote DIctionary Server)是一个开源(BSD许可),内存存储的数据结构服务器,可用作数据库,高速缓存和消息队列,是一个高性能的key-value数据库. Redis与其他key-value缓存产品有以下三个特点: Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用. Redis不仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储. Redis支持

ExtJs 入门教程

ExtJs 入门教程一[学习方法] ExtJs 入门教程二[Hello World] ExtJs 入门教程三[窗体:Window组件] ExtJs 入门教程四[表单:FormPanel] ExtJs 入门教程五[文本框:TextField] ExtJs 入门教程六[按钮:Button] ExtJs 入门教程七[登陆窗体Demo:Login] ExtJs 入门教程八[脚本调试Firefox:firebug] ExtJs 入门教程九[数字字段:NumberField.隐藏字段Hidden.日期字段:

java操作memcached入门教程demo代码

原文:java操作memcached入门教程demo代码 源代码下载地址:http://www.zuidaima.com/share/1550463754996736.htm 参考地址: http://www.open-open.com/lib/view/open1357831114183.html http://tech.idv2.com/2008/07/10/memcached-001/ 感谢 京-java牛-ID号1  感谢 锡-SuperPrivate-195 在网上搜索了部分代码,一个

Android基础入门教程——7.5.5 WebView缓存问题

Android基础入门教程--7.5.5 WebView缓存问题 标签(空格分隔): Android基础入门教程 本节引言: 现在很多门户类信息网站,比如虎嗅,ifanr,钛媒体等等的APP,简单点说是信息阅读类的APP,很多 都是直接嵌套一个WebView用来显示相关资讯的,这可能就涉及到了WebView的缓存了!所谓的页面缓存 就是指:保存加载一个网页时所需的HTML,JS,CSS等页面相关的数据以及其他资源,当没网的时候或者 网络状态较差的时候,加载本地保存好的相关数据!而实现这个缓存的方

NetBeans工具学习之道:NetBeans IDE Java 快速入门教程

欢迎使用 NetBeans IDE! 本教程通过指导您创建一个简单的 "Hello World" Java 控制台应用程序,简要介绍 NetBeans IDE 工作流.学习完本教程后,您将对如何在 IDE 中创建和运行应用程序有一个基本了解. 学习完本教程所需的时间不到 10 分钟. 学完本教程后,您可以转至文档.培训和支持页中链接的学习资源.这些学习资源提供了综合性教程,其中重点介绍适用各种应用程序类型的更多 IDE 功能和编程技巧.如果您不希望创建 "Hello Worl

Android基础入门教程——2.3.12 Date &amp; Time组件(下)

Android基础入门教程--2.3.12 Date & Time组件(下) 标签(空格分隔): Android基础入门教程 本节引言: 本节我们来继续学习Android系统给我们提供的几个原生的Date & Time组件,他们分别是: DatePicker(日期选择器),TimePicker(时间选择器),CalendarView(日期视图),好吧, 其实一开始让我扣这几个玩意我是拒绝的,因为在我的印象里,他们是这样的: 简直把我丑哭了,有木有,终于知道为什么那么多人喜欢自定义这种类型的

TestNG 入门教程&lt;Java 入门&gt;

TestNG 入门教程 摘要:http://www.cnblogs.com/TankXiao/p/3888070.html 国庆7天假期,大部分朋友都出去旅游了,微信圈里全是晒旅游的照片, 东南亚游,欧洲游呀,真是羡慕呀. 悲惨的我只去了上海野生动物园, 在家休息,利用这段假期,把之前学过的东西都总结下. 我前段时间加班太多了,每天忙碌工作,都没精力去管自己的学习新技能的计划, 博客也没写几篇,很多想做的事情都因为工作太忙而耽搁了. 所以工作太忙了也不好,没有精力关注工作以外的事情. 最近写自动

Java的进程内缓存框架:EhCache (转)

EhCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. Ehcache缓存的特点: 1. 快速. 2. 简单. 3. 多种缓存策略 4. 缓存数据有两级:内存和磁盘,因此无需担心容量问题 5. 缓存数据会在虚拟机重启的过程中写入磁盘 6. 可以通过RMI.可插入API等方式进行分布式缓存 7. 具有缓存和缓存管理器的侦听接口 8. 支持多缓存管理器实例,以及一个实例的多个缓存区域 9. 提供Hibernate的缓存实现 E

程序设计C语言二级考试教程 Java基础视频教程 安卓软件开发教程 Unity3D游戏制作入门教程

热门推荐电脑办公计算机基础知识教程 Excel2010基础教程 Word2010基础教程 PPT2010基础教程 五笔打字视频教程 Excel函数应用教程 Excel VBA基础教程 WPS2013表格教程 更多>平面设计PhotoshopCS5教程 CorelDRAW X5视频教程 Photoshop商业修图教程 Illustrator CS6视频教程 更多>室内设计3Dsmax2012教程 效果图实例提高教程 室内设计实战教程 欧式效果图制作实例教程 AutoCAD2014室内设计 Aut