日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2024/7/23 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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框架就搭建完成。

總結

以上是生活随笔為你收集整理的java将对象 缓存_ehcache java 对象缓存怎么实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。