亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

EHCache講解

2019-11-10 17:41:22
字體:
來源:轉載
供稿:網友

EHCache是來自sourceforge(http://ehcache.sourceforge.net/)的開源項目,也是純java實現的簡單、快速的Cache組件。EHCache支持內存和磁盤的緩存,支持LRU、LFU和FIFO多種淘汰算法,支持分布式的Cache,可以作為Hibernate的緩存插件。同時它也能提供基于Filter的Cache,該Filter可以緩存響應的內容并采用Gzip壓縮提高響應速度。

1. EHCache API的基本用法

1.1 CacheManager類

作用:主要負責讀取配置文件,并根據配置文件創建和管理Cache類。默認讀取CLASSPATH下的ehcache.xml

// 使用默認配置文件創建CacheManagerCacheManager manager = CacheManager.create();// 通過manager可以生成指定名稱的Cache對象Cache cache = cache = manager.getCache("myCache");// 使用manager移除指定名稱的Cache對象manager.removeCache("myCache");//可用來移除所有的Cachemanager.removalAll();//關閉CacheManagermanager.shutdown();

1.2 Cache類

//往cache中添加元素Element element = new Element("key", "value");cache.put(element);//從cache中取回元素Element element = cache.get("key");element.getValue();//從Cache中移除一個元素cache.remove("key");

這里需要注意的是對于緩存的對象都是必須可序列化的。

1.3 配置文件

配置文件ehcache.xml中命名為myCache的緩存配置:

<cache name="myCache" //該名字與manager里操作的名字一樣 maxElementsInMemory="10000" // 緩存中允許創建的最大對象數 eternal="false" //緩存中對象是否為永久。如果是,超時設置將被忽略,對象從不過期。 overflowToDisk="true" //內存不足時,是否啟用磁盤緩存 timeToIdleSeconds="300" //緩存數據的鈍化時間,即在一個元素消亡之前,兩次訪問時間的最大時間間隔值。這只能在元素不是永久駐留時有效,如果該值是 0 就意味著元素可以停頓無窮長的時間。 timeToLiveSeconds="600" //緩存數據的生存時間,也就是一個元素從構建到消亡的最大時間間隔值。這只能在元素不是永久駐留時有效,如果該值是0就意味著元素可以停頓無窮長的時間。 memoryStoreEvictionPolicy="LFU" //緩存滿了之后的淘汰算法。LFU算法直接淘汰使用比較少的對象,在內存保留的都是一些經常訪問的對象。對于大部分網站項目,該算法比較適用。 />

如果應用需要配置多個不同命名并采用不同參數的Cache,可以相應修改配置文件,增加需要的Cache配置即可。

2. 利用SPRing APO整合EHCache

首先,在CLASSPATH下面放置ehcache.xml配置文件。在Spring的配置文件中先添加如下cacheManager配置:

<bean id="cacheManager1" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation"> <value>classpath:ehcache.xml</value> </property></bean>// 配置myCache:<bean id="myCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager" ref="cacheManager1" /> <property name="cacheName"> <value>myCache</value> <!-- 在咖啡 --> </property></bean>

接下來,寫一個實現org.aopalliance.intercept.MethodInterceptor接口的攔截器類。 有了攔截器就可以有選擇性的配置想要緩存的 bean 方法。如果被調用的方法配置為可緩存,攔截器將為該方法生成 cache key 并檢查該方法返回的結果是否已緩存。如果已緩存,就返回緩存的結果,否則再次執行被攔截的方法,并緩存結果供下次調用。具體代碼如下:

public class MethodCacheInterceptor implements MethodInterceptor,InitializingBean { private Cache cache; public void setCache(Cache cache) { this.cache = cache; } public void afterPropertiesSet() throws Exception { Assert.notNull(cache,"A cache is required. Use setCache(Cache) to provide one."); } public Object invoke(MethodInvocation invocation) throws Throwable { String targetName = invocation.getThis().getClass().getName(); String methodName = invocation.getMethod().getName(); Object[] arguments = invocation.getArguments(); Object result; String cacheKey = getCacheKey(targetName, methodName, arguments); Element element = null; /**為什么一定要同步? Cache對象本身的get和put操作是同步的。 如果我們緩存的數據來自數據庫查詢,在沒有這段同步代碼時,當key不存在或者key對應的對象已經過期時, 在多線程并發訪問的情況下,許多線程都會重新執行該方法,由于對數據庫進行重新查詢代價是比較昂貴的, 同步后,如果一個線程從數據庫拿到了數據,則后面的線程不需要去數據庫再查詢了。 */ synchronized (this){ element = cache.get(cacheKey); if (element == null) { //調用實際的方法 result = invocation.proceed(); element = new Element(cacheKey, (Serializable) result); cache.put(element); } } return element.getValue(); } 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(); }}

接下來,完成攔截器和Bean的配置:

<bean id="methodCacheInterceptor" class="com.xiebing.utils.interceptor.MethodCacheInterceptor"> <property name="cache"> <ref local="myCache" /> </property></bean><bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="methodCacheInterceptor" /> </property> <property name="patterns"> <list> <!-- 所有以myMethod結尾的方法都會被緩存 --> <value>.*myMethod</value> </list> </property></bean><bean id="myServiceBean" class="com.xiebing.ehcache.spring.MyServiceBean"></bean><bean id="myService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <ref local="myServiceBean" /> </property> <property name="interceptorNames"> <list> <value>methodCachePointCut</value> </list> </property></bean>

使用AOP的方式極大地提高了系統的靈活性,通過修改配置文件就可以實現對方法結果的緩存,所有的對Cache的操作都封裝在了攔截器的實現中。

3. CachingFilter功能

作用:可以對HTTP響應的內容進行緩存。這種方式緩存數據的粒度比較粗,例如緩存整張頁面。 優點:使用簡單、效率高 缺點:不夠靈活,可重用程度不高。 EHCache使用SimplePageCachingFilter類實現Filter緩存。該類繼承自CachingFilter,有默認產生cache key的calculateKey()方法,該方法使用HTTP請求的URI和查詢條件來組成key。也可以自己實現一個Filter,同樣繼承CachingFilter類,然后覆寫calculateKey()方法,生成自定義的key。 有時在使用Ajax時,為保證JS請求的數據不被瀏覽器緩存,每次請求都會帶有一個隨機數參數i。如果使用SimplePageCachingFilter,那么每次生成的key都不一樣,緩存就沒有意義了。這種情況下,我們就會覆寫calculateKey()方法。 要使用SimplePageCachingFilter,首先在配置文件ehcache.xml中,增加下面的配置:

<filter> <filter-name>SimplePageCachingFilter</filter-name> <filter-class>net.sf.ehcache.constructs.web.filter.SimplePageCachingFilter</filter-class></filter><filter-mapping> <filter-name>SimplePageCachingFilter</filter-name> <url-pattern>/test.jsp</url-pattern></filter-mapping>

下面我們寫一個簡單的test.jsp文件進行測試,緩存后的頁面每次刷新,在600秒內顯示的時間都不會發生變化的。代碼如下:

<%out.println(new Date());%>

CachingFilter輸出的數據會根據瀏覽器發送的Accept-Encoding頭信息進行Gzip壓縮。經過測試,Gzip壓縮后的數據量是原來的1/4,速度是原來的4-5倍,所以緩存加上壓縮,效果非常明顯。

在使用Gzip壓縮時,需注意兩個問題: 1. Filter在進行Gzip壓縮時,采用系統默認編碼,對于使用GBK編碼的中文網頁來說,需要將操作系統的語言設置為:zh_CN.GBK,否則會出現亂碼的問題。 2. 默認情況下CachingFilter會根據瀏覽器發送的請求頭部所包含的Accept-Encoding參數值來判斷是否進行Gzip壓縮。雖然IE6/7瀏覽器是支持Gzip壓縮的,但是在發送請求的時候卻不帶該參數。為了對IE6/7也能進行Gzip壓縮,可以通過繼承CachingFilter,實現自己的Filter,然后在具體的實現中覆寫方法acceptsGzipEncoding。 具體實現參考:

protected boolean acceptsGzipEncoding(HttpServletRequest request) { final boolean ie6 = headerContains(request, "User-Agent", "MSIE 6.0"); final boolean ie7 = headerContains(request, "User-Agent", "MSIE 7.0"); return acceptsEncoding(request, "gzip") || ie6 || ie7;}

4. EHCache在Hibernate中的使用

EHCache可以作為Hibernate的二級緩存使用。在hibernate.cfg.xml中需增加如下設置:

<prop key="hibernate.cache.provider_class"> org.hibernate.cache.EhCacheProvider</prop>

然后在Hibernate映射文件的每個需要Cache的Domain中,加入類似如下格式信息:

<cache usage="read-write|nonstrict-read-write|read-only" />

比如:

<cache usage="read-write" />

最后在配置文件ehcache.xml中增加一段cache的配置,其中name為該domain的類名。

<cache name="domain.class.name"maxElementsInMemory="10000"eternal="false"timeToIdleSeconds="300"timeToLiveSeconds="600"overflowToDisk="false"/>

5. EHCache的監控

對于Cache的使用,除了功能,在實際的系統運營過程中,我們會比較關注每個Cache對象占用的內存大小和Cache的命中率。有了這些數據,我們就可以對Cache的配置參數和系統的配置參數進行優化,使系統的性能達到最優。EHCache提供了方便的API供我們調用以獲取監控數據,其中主要的方法有:

//得到緩存中的對象數cache.getSize();//得到緩存對象占用內存的大小cache.getMemoryStoreSize();//得到緩存讀取的命中次數cache.getStatistics().getCacheHits()//得到緩存讀取的錯失次數cache.getStatistics().getCacheMisses()

6. 分布式緩存

EHCache從1.2版本開始支持分布式緩存。分布式緩存主要解決集群環境中不同的服務器間的數據的同步問題。具體的配置如下: 在配置文件ehcache.xml中加入

<cacheManagerPeerProviderFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446"/><cacheManagerPeerListenerFactory class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/>

另外,需要在每個cache屬性中加入

<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/>

例如:

<cache name="demoCache"maxElementsInMemory="10000"eternal="true"overflowToDisk="true" > <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"/></cache>

總結

EHCache是一個非常優秀的基于Java的Cache實現。它簡單、易用,而且功能齊全,并且非常容易與Spring、Hibernate等流行的開源框架進行整合。通過使用EHCache可以減少網站項目中數據庫服務器的訪問壓力,提高網站的訪問速度,改善用戶的體驗。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美大片第1页| 精品亚洲一区二区三区在线观看| 欧美专区福利在线| 欧美一级在线亚洲天堂| 国产精品久久久久影院日本| 欧美日韩亚洲91| 久久国产精品久久久| 欧美激情国产高清| 97久久精品人搡人人玩| 日韩福利视频在线观看| 久久精品电影一区二区| 成人精品aaaa网站| 91日本在线视频| 亚洲精品av在线播放| 中文字幕精品网| 色偷偷av亚洲男人的天堂| 91精品国产沙发| 亚洲午夜未满十八勿入免费观看全集| 欧美成人午夜免费视在线看片| 一本大道久久加勒比香蕉| 久久久国产精品视频| 日本免费一区二区三区视频观看| xxxxxxxxx欧美| 欧美激情视频播放| 国模gogo一区二区大胆私拍| 亲子乱一区二区三区电影| 国产精品999| 国产精品久久在线观看| 欧美极品在线视频| 永久免费精品影视网站| 亚洲专区中文字幕| 国产脚交av在线一区二区| 国产精品久久久久久久9999| 国产日韩欧美在线播放| 日韩亚洲欧美中文在线| 久久午夜a级毛片| 国产精品白嫩初高中害羞小美女| 精品一区二区三区三区| 久久久久久久影院| 亚洲天堂精品在线| 国产精品aaaa| 欧美日韩一区二区三区在线免费观看| 欧美一区二区三区精品电影| 日韩精品极品在线观看| 国产精品羞羞答答| 福利视频一区二区| 欧美精品精品精品精品免费| 91精品国产91久久久久福利| 欧美成在线视频| 久久免费高清视频| 亚洲视频999| 日韩视频―中文字幕| 伊人伊成久久人综合网小说| 久久久国产精品免费| 欧美一区二区三区图| 国产精品第一页在线| 538国产精品一区二区在线| 国产激情999| 久久久97精品| 亚洲精品电影网在线观看| 国产91成人video| 成人高清视频观看www| 国产91精品视频在线观看| 欧美日韩国产一区二区三区| 尤物yw午夜国产精品视频明星| 日韩精品中文字幕在线| 精品久久久久久久久中文字幕| 亚洲精品成人免费| 国产精品久久久久久久久免费| 欲色天天网综合久久| 久久国产精品电影| 成人激情视频免费在线| 精品国产欧美一区二区三区成人| 国产欧美精品在线播放| 91高清视频在线免费观看| 国产精品美乳在线观看| 欧美成人午夜剧场免费观看| 日韩黄色高清视频| 国产亚洲精品久久久久久| 91免费看片在线| 国产精品免费视频xxxx| 亚洲偷欧美偷国内偷| 97精品欧美一区二区三区| 久久影视电视剧免费网站清宫辞电视| 日本久久亚洲电影| 亚洲欧美日韩在线高清直播| 欧美交受高潮1| 欧美日韩免费区域视频在线观看| 精品久久久久久中文字幕| 性色av一区二区三区红粉影视| 国产精品色视频| 91中文在线视频| 92国产精品久久久久首页| 日本精品中文字幕| 国产成人小视频在线观看| 国内精品美女av在线播放| 日韩中文在线中文网在线观看| 久久精品国产亚洲精品2020| 一区二区三区无码高清视频| 日本在线观看天堂男亚洲| 亚洲国产精品久久久| 欧美在线性视频| 亚洲色图色老头| 国色天香2019中文字幕在线观看| 欧美激情在线播放| 日韩亚洲国产中文字幕| 最新的欧美黄色| 4444欧美成人kkkk| 亚洲国产欧美久久| 久久人91精品久久久久久不卡| 国产精品久久中文| 97碰碰碰免费色视频| 久久久久久久久久久成人| 久久精品国产欧美亚洲人人爽| 亚洲精品免费一区二区三区| 日韩在线欧美在线| 日韩av日韩在线观看| 91亚洲va在线va天堂va国| 日韩综合视频在线观看| 国产精品av在线播放| 日韩精品视频免费专区在线播放| 国产日韩欧美电影在线观看| 亚洲第一偷拍网| 成人亚洲激情网| 国产三级精品网站| 国产午夜精品一区二区三区| 国产精品在线看| 欧美黄色片在线观看| 97视频在线观看免费高清完整版在线观看| 欧美亚洲国产日韩2020| 欧美性xxxxx| 91精品91久久久久久| 在线亚洲午夜片av大片| 热门国产精品亚洲第一区在线| 日韩欧美aⅴ综合网站发布| 亚洲黄色www网站| 国产高清视频一区三区| 国产精品96久久久久久又黄又硬| 91精品在线观看视频| 亚洲乱亚洲乱妇无码| 97久久伊人激情网| 久久久久久久久久久91| 色噜噜亚洲精品中文字幕| 国产成人高清激情视频在线观看| 亚洲成人av片在线观看| 亚洲电影免费观看高清完整版在线| 国产啪精品视频网站| 91精品国产高清久久久久久久久| 国产亚洲激情视频在线| 少妇av一区二区三区| 一区二区欧美在线| 国产69久久精品成人| 亚洲视频在线免费观看| 久久91精品国产91久久跳| 国产丝袜一区二区三区| 国产亚洲精品va在线观看| 国产日韩欧美中文在线播放| 亚洲二区在线播放视频| 亚洲女人被黑人巨大进入al| 欧美大片网站在线观看| 欧美日本在线视频中文字字幕| 欧美激情喷水视频| 国产91在线高潮白浆在线观看| 国产精品美乳在线观看|