EHcache.docx
- 文档编号:8225708
- 上传时间:2023-01-30
- 格式:DOCX
- 页数:13
- 大小:21.51KB
EHcache.docx
《EHcache.docx》由会员分享,可在线阅读,更多相关《EHcache.docx(13页珍藏版)》请在冰豆网上搜索。
EHcache
Ehcache整合Spring使用页面、对象缓存
Ehcache在很多项目中都出现过,用法也比较简单。
一般的加些配置就可以了,而且Ehcache可以对页面、对象、数据进行缓存,同时支持集群/分布式缓存。
如果整合Spring、Hibernate也非常的简单,Spring对Ehcache的支持也非常好。
EHCache支持内存和磁盘的缓存,支持LRU、LFU和FIFO多种淘汰算法,支持分布式的Cache,可以作为Hibernate的缓存插件。
同时它也能提供基于Filter的Cache,该Filter可以缓存响应的内容并采用Gzip压缩提高响应速度。
一、准备工作
如果你的系统中已经成功加入Spring、Hibernate;那么你就可以进入下面Ehcache的准备工作。
1、下载jar包
Ehcache对象、数据缓存:
http:
//ehcache.org/downloads/destination?
name=ehcache-core-2.5.2-distribution.tar.gz&bucket=tcdistributions&file=ehcache-core-2.5.2-distribution.tar.gz
Web页面缓存:
http:
//ehcache.org/downloads/destination?
name=ehcache-web-2.0.4-distribution.tar.gz&bucket=tcdistributions&file=ehcache-web-2.0.4-distribution.tar.gz
2、需要添加如下jar包到lib目录下
ehcache-core-2.5.2.jar
ehcache-web-2.0.4.jar主要针对页面缓存
3、当前工程的src目录中加入配置文件
ehcache.xml
ehcache.xsd
这些配置文件在ehcache-core这个jar包中可以找到
二、Ehcache基本用法
CacheManagercacheManager=CacheManager.create();
//或者
cacheManager=CacheManager.getInstance();
//或者
cacheManager=CacheManager.create("/config/ehcache.xml");
//或者
cacheManager=CacheManager.create("http:
//localhost:
8080/test/ehcache.xml");
cacheManager=CacheManager.newInstance("/config/ehcache.xml");
//.......
//获取ehcache配置文件中的一个cache
Cachesample=cacheManager.getCache("sample");
//获取页面缓存
BlockingCachecache=newBlockingCache(cacheManager.getEhcache("SimplePageCachingFilter"));
//添加数据到缓存中
Elementelement=newElement("key","val");
sample.put(element);
//获取缓存中的对象,注意添加到cache中对象要序列化实现Serializable接口
Elementresult=sample.get("key");
//删除缓存
sample.remove("key");
sample.removeAll();
//获取缓存管理器中的缓存配置名称
for(StringcacheName:
cacheManager.getCacheNames()){
System.out.println(cacheName);
}
//获取所有的缓存对象
for(Objectkey:
cache.getKeys()){
System.out.println(key);
}
//得到缓存中的对象数
cache.getSize();
//得到缓存对象占用内存的大小
cache.getMemoryStoreSize();
//得到缓存读取的命中次数
cache.getStatistics().getCacheHits();
//得到缓存读取的错失次数
cache.getStatistics().getCacheMisses();
三、页面缓存
页面缓存主要用Filter过滤器对请求的url进行过滤,如果该url在缓存中出现。
那么页面数据就从缓存对象中获取,并以gzip压缩后返回。
其速度是没有压缩缓存时速度的3-5倍,效率相当之高!
其中页面缓存的过滤器有CachingFilter,一般要扩展filter或是自定义Filter都继承该CachingFilter。
CachingFilter功能可以对HTTP响应的内容进行缓存。
这种方式缓存数据的粒度比较粗,例如缓存整张页面。
它的优点是使用简单、效率高,缺点是不够灵活,可重用程度不高。
EHCache使用SimplePageCachingFilter类实现Filter缓存。
该类继承自CachingFilter,有默认产生cachekey的calculateKey()方法,该方法使用HTTP请求的URI和查询条件来组成key。
也可以自己实现一个Filter,同样继承CachingFilter类,然后覆写calculateKey()方法,生成自定义的key。
CachingFilter输出的数据会根据浏览器发送的Accept-Encoding头信息进行Gzip压缩。
在使用Gzip压缩时,需注意两个问题:
1.Filter在进行Gzip压缩时,采用系统默认编码,对于使用GBK编码的中文网页来说,需要将操作系统的语言设置为:
zh_CN.GBK,否则会出现乱码的问题。
2.默认情况下CachingFilter会根据浏览器发送的请求头部所包含的Accept-Encoding参数值来判断是否进行Gzip压缩。
虽然IE6/7浏览器是支持Gzip压缩的,但是在发送请求的时候却不带该参数。
为了对IE6/7也能进行Gzip压缩,可以通过继承CachingFilter,实现自己的Filter,然后在具体的实现中覆写方法acceptsGzipEncoding。
具体实现参考:
protectedbooleanacceptsGzipEncoding(HttpServletRequestrequest){
booleanie6=headerContains(request,"User-Agent","MSIE6.0");
booleanie7=headerContains(request,"User-Agent","MSIE7.0");
returnacceptsEncoding(request,"gzip")||ie6||ie7;
}
在ehcache.xml中加入如下配置
xmlversion="1.0"encoding="gbk"?
>
xsi="http: //www.w3.org/2001/XMLSchema-instance"xsi: noNamespaceSchemaLocation="ehcache.xsd"> -- 配置自定义缓存 maxElementsInMemory: 缓存中允许创建的最大对象数 eternal: 缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。 timeToIdleSeconds: 缓存数据的钝化时间,也就是在一个元素消亡之前, 两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效, 如果该值是0就意味着元素可以停顿无穷长的时间。 timeToLiveSeconds: 缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值, 这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。 overflowToDisk: 内存不足时,是否启用磁盘缓存。 memoryStoreEvictionPolicy: 缓存满了之后的淘汰算法。 --> maxElementsInMemory="10000" eternal="false" overflowToDisk="false" timeToIdleSeconds="900" timeToLiveSeconds="1800" memoryStoreEvictionPolicy="LFU"/> 具体代码: packagecom.hoo.ehcache.filter; importjava.util.Enumeration; importjavax.servlet.FilterChain; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importnet.sf.ehcache.CacheException; importnet.sf.ehcache.constructs.blocking.LockTimeoutException; importnet.sf.ehcache.constructs.web.AlreadyCommittedException; importnet.sf.ehcache.constructs.web.AlreadyGzippedException; importnet.sf.ehcache.constructs.web.filter.FilterNonReentrantException; importnet.sf.ehcache.constructs.web.filter.SimplePageCachingFilter; importmons.lang.StringUtils; importorg.apache.log4j.Logger; /** *function: mobile页面缓存过滤器 *@authorhoojo *@createDate2012-7-4上午09: 34: 30 *@filePageEhCacheFilter.java *@packagecom.hoo.ehcache.filter *@projectEhcache *@blog *@emailhoojo_@ *@version1.0 */ publicclassPageEhCacheFilterextendsSimplePageCachingFilter{ privatefinalstaticLoggerlog=Logger.getLogger(PageEhCacheFilter.class); privatefinalstaticStringFILTER_URL_PATTERNS="patterns"; privatestaticString[]cacheURLs; privatevoidinit()throwsCacheException{ Stringpatterns=filterConfig.getInitParameter(FILTER_URL_PATTERNS); cacheURLs=StringUtils.split(patterns,","); } @Override protectedvoiddoFilter(finalHttpServletRequestrequest, finalHttpServletResponseresponse,finalFilterChainchain) throwsAlreadyGzippedException,AlreadyCommittedException, FilterNonReentrantException,LockTimeoutException,Exception{ if(cacheURLs==null){ init(); } Stringurl=request.getRequestURI(); booleanflag=false; if(cacheURLs! =null&&cacheURLs.length>0){ for(StringcacheURL: cacheURLs){ if(url.contains(cacheURL.trim())){ flag=true; break; } } } //如果包含我们要缓存的url就缓存该页面,否则执行正常的页面转向 if(flag){ Stringquery=request.getQueryString(); if(query! =null){ query="? "+query; } log.info("当前请求被缓存: "+url+query); super.doFilter(request,response,chain); }else{ chain.doFilter(request,response); } } @SuppressWarnings("unchecked") privatebooleanheaderContains(finalHttpServletRequestrequest,finalStringheader,finalStringvalue){ logRequestHeaders(request); finalEnumerationaccepted=request.getHeaders(header); while(accepted.hasMoreElements()){ finalStringheaderValue=(String)accepted.nextElement(); if(headerValue.indexOf(value)! =-1){ returntrue; } } returnfalse; } /** *@seenet.sf.ehcache.constructs.web.filter.Filter#acceptsGzipEncoding(javax.servlet.http.HttpServletRequest) *function: 兼容ie6/7gzip压缩 *@authorhoojo *@createDate2012-7-4上午11: 07: 11 */ @Override protectedbooleanacceptsGzipEncoding(HttpServletRequestrequest){ booleanie6=headerContains(request,"User-Agent","MSIE6.0"); booleanie7=headerContains(request,"User-Agent","MSIE7.0"); returnacceptsEncoding(request,"gzip")||ie6||ie7; } } 这里的PageEhCacheFilter继承了SimplePageCachingFilter,一般情况下SimplePageCachingFilter就够用了,这里是为了满足当前系统需求才做了覆盖操作。 使用SimplePageCachingFilter需要在web.xml中配置cacheName,cacheName默认是SimplePageCachingFilter,对应ehcache.xml中的cache配置。 在web.xml中加入如下配置 --缓存、gzip压缩核心过滤器--> --配置你需要缓存的url--> 当第一次请求这些页面后,这些页面就会被添加到缓存中,以后请求这些页面将会从缓存中获取。 你可以在cache.jsp页面中用小脚本来测试该页面是否被缓存。 <%=newDate()%>如果时间是变动的,则表示该页面没有被缓存或是缓存已经过期,否则则是在缓存状态了。 四、对象缓存 对象缓存就是将查询的数据,添加到缓存中,下次再次查询的时候直接从缓存中获取,而不去数据库中查询。 对象缓存一般是针对方法、类而来的,结合Spring的Aop对象、方法缓存就很简单。 这里需要用到切面编程,用到了Spring的MethodInterceptor或是用@Aspect。 代码如下: packagemon.ehcache; importjava.io.Serializable; importnet.sf.ehcache.Cache; importnet.sf.ehcache.Element; importorg.aopalliance.intercept.MethodInterceptor; importorg.aopalliance.intercept.MethodInvocation; importorg.apache.log4j.Logger; importorg.springframework.beans.factory.InitializingBean; /** *function: 缓存方法拦截器核心代码 *@authorhoojo *@createDate2012-7-2下午06: 05: 34 *@fileMethodCacheInterceptor.java *@packagemon.ehcache *@projectEhcache *@blog *@emailhoojo_@ *@version1.0 */ publicclassMethodCacheInterceptorimplementsMethodInterceptor,InitializingBean{ privatestaticfinalLoggerlog=Logger.getLogger(MethodCacheInterceptor.class); privateCachecache; publicvoidsetCache(Cachecache){ this.cache=cache; } publicvoidafterPropertiesSet()throwsException{ log.info(cache+"Acacheisrequired.UsesetCache(Cache)toprovideone."); } publicObjectinvoke(MethodInvocationinvocation)throwsThrowable{ StringtargetName=invocation.getThis().getClass().getName(); StringmethodName=invocation.getMethod().getName(); Object[]arguments=invocation.getArguments(); Objectresult; StringcacheKey=getCacheKey(targetName,methodName,arguments); Elementelement=null; synchronized(this){ element=cache.get(cacheKey); if(element==null){ log.info(cacheKey+"加入到缓存: "+cache.getName()); //调用实际的方法 result=invocation.proceed(); element=newElement(cacheKey,(Serializable)result); cache.put(element); }else{ log.info(cacheKey+"使用缓存: "+cache.getName()); } } returnelement.getValue(); } /** *function: 返回具体的方法全路径名称参数 *@authorhoojo
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- EHcache
![提示](https://static.bdocx.com/images/bang_tan.gif)