1. 程式人生 > >用OSCache進行緩存對象

用OSCache進行緩存對象

can onu 重要 初始 valueof star oba 項目組 希望

1、OSCache是什麽?
OSCache標記庫由OpenSymphony設計,它是一種開創性的緩存方案,它提供了在現有JSP頁面之內實現內存緩存的功能。OSCache是個一個被廣泛采用的高性能的J2EE緩存框架,OSCache還能應用於任何Java應用程序的普通的緩存解決方案。
2、OSCache的特點
(1) 緩存任何對象:你可以不受限制的緩存部分jsp頁面或HTTP請求,任何java對象都可以緩存。
(2) 擁有全面的API:OSCache API允許你通過編程的方式來控制所有的OSCache特性。
(3) 永久緩存:緩存能被配置寫入硬盤,因此允許在應用服務器的多次生命周期間緩存創建開銷昂貴的數據。
(4) 支持集群:集群緩存數據能被單個的進行參數配置,不需要修改代碼。
(5) 緩存過期:你可以有最大限度的控制緩存對象的過期,包括可插入式的刷新策略(如果默認性能不能滿足需要時)。
3、OSCache的安裝與配置
4、有關“用OSCache進行緩存對象”的研究


這個是我今天要說的東西。網上對於OSCache緩存Web頁面很多說明和例子,但對於緩存對象方面說得不多,我就把自已寫得一些東西放出來,讓大家看一看是怎樣緩存對象的!
我基於GeneralCacheAdministrator類來寫的BaseCache類
Java代碼

  1. package com.klstudio.cache;
  2. import java.util.Date;
  3. import com.opensymphony.oscache.base.NeedsRefreshException;
  4. import com.opensymphony.oscache.general.GeneralCacheAdministrator;
  5. public class BaseCache extends GeneralCacheAdministrator {
  6. //過期時間(單位為秒);
  7. private int refreshPeriod;
  8. //關鍵字前綴字符;
  9. private String keyPrefix;
  10. private static final long serialVersionUID = -4397192926052141162L;
  11. public BaseCache(String keyPrefix,int refreshPeriod){
  12. super();
  13. this.keyPrefix = keyPrefix;
  14. this.refreshPeriod = refreshPeriod;
  15. }
  16. //添加被緩存的對象;
  17. public void put(String key,Object value){
  18. this.putInCache(this.keyPrefix+"_"+key,value);
  19. }
  20. //刪除被緩存的對象;
  21. public void remove(String key){
  22. this.flushEntry(this.keyPrefix+"_"+key);
  23. }
  24. //刪除所有被緩存的對象;
  25. public void removeAll(Date date){
  26. this.flushAll(date);
  27. }
  28. public void removeAll(){
  29. this.flushAll();
  30. }
  31. //獲取被緩存的對象;
  32. public Object get(String key) throws Exception{
  33. try{
  34. return this.getFromCache(this.keyPrefix+"_"+key,this.refreshPeriod);
  35. } catch (NeedsRefreshException e) {
  36. this.cancelUpdate(this.keyPrefix+"_"+key);
  37. throw e;
  38. }
  39. }
  40. }


通過CacheManager類來看怎樣緩存對象的,這個類中所用的News只是具體功能的類,我就不貼出來了,你可以自己寫一個!
Java代碼

  1. package com.klstudio;
  2. import com.klstudio.News;
  3. import com.klstudio.cache.BaseCache;
  4. public class CacheManager {
  5. private BaseCache newsCache;
  6. private static CacheManager instance;
  7. private static Object lock = new Object();
  8. public CacheManager() {
  9. //這個根據配置文件來,初始BaseCache而已;
  10. newsCache = new BaseCache("news",1800);
  11. }
  12. public static CacheManager getInstance(){
  13. if (instance == null){
  14. synchronized( lock ){
  15. if (instance == null){
  16. instance = new CacheManager();
  17. }
  18. }
  19. }
  20. return instance;
  21. }
  22. public void putNews(News news) {
  23. // TODO 自動生成方法存根
  24. newsCache.put(news.getID(),news);
  25. }
  26. public void removeNews(String newsID) {
  27. // TODO 自動生成方法存根
  28. newsCache.remove(newsID);
  29. }
  30. public News getNews(String newsID) {
  31. // TODO 自動生成方法存根
  32. try {
  33. return (News) newsCache.get(newsID);
  34. } catch (Exception e) {
  35. // TODO 自動生成 catch 塊
  36. System.out.println("getNews>>newsID["+newsID+"]>>"+e.getMessage());
  37. News news = new News(newsID);
  38. this.putNews(news);
  39. return news;
  40. }
  41. }
  42. public void removeAllNews() {
  43. // TODO 自動生成方法存根
  44. newsCache.removeAll();
  45. }
  46. }
一、緩存整個頁面 在OSCache組件中提供了一個CacheFilter用於實現頁面級的緩存,主要用於對web應用中的某些動態頁面進行緩存,尤其是那些需要生成PDF格式文件/報表、圖片文件等的頁面,不僅減少了數據庫的交互、減少數據庫服務器的壓力,而且對於減少web服務器的性能消耗有很顯著的效果。 這種功能的實現是通過在web.xml中進行配置來決定緩存哪一個或者一組頁面,而且還可以設置緩存的相關屬性,這種基於配置文件的實現方式對於J2EE來說應該是一種標準的實現方式了。 [註] 只有客戶訪問時返回http頭信息中代碼為200(也就是訪問已經成功)的頁面信息才能夠被緩存。 修改web.xml,增加如下內容,確定對/testContent.jsp頁面進行緩存。 <filter> <filter-name>CacheFilter</filter-name> <filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class> <init-param> <param-name>time</param-name> <param-value>600</param-value> </init-param> <init-param> <param-name>scope</param-name> <param-value>session</param-value> </init-param> </filter> <filter-mapping> <filter-name>CacheFilter</filter-name> <!-對所有jsp頁面內容進行緩存--> <url-pattern>*.jsp</url-pattern> </filter-mapping> 在頁面級緩存的情況下,可以通過設置CacheFilter的初始屬性來決定緩存的一些特性:time屬性設置緩存的時間段,默認為3600秒,可以根據自己的需要只有的設置,而scope屬性設置,默認為application,可選項包括application、session。 二、緩存頁面的部分 1、OSCache標簽庫配置 (1) 從src\webapp\WEB-INF\classes或etc目錄取得soscache.tld文件,放在CLASSPATH下(src根目錄或發布環境的/WEB-INF/classes 目錄)。該文件定義了OSCache的定義。 (2) 將下列代碼加入web.xml文件中: <taglib> <taglib-uri>oscache</taglib-uri> <taglib-location>/WEB-INF/classes/oscache.tld</taglib-location> </taglib> 2、cache標簽 這是OSCache提供的標簽庫中最重要的一個標簽,包括在標簽中的內容將應用緩存機制進行處理,處理的方式將取決於編程者對cache標簽屬性的設置。 第一次請求到達時,標簽中的內容被處理並且緩存起來,當下一個請求到達時,緩存系統會檢查這部分內容的緩存是否已經失效,主要是以下幾項: (1)緩存時間超過了cache標簽設置的time或者duration屬性規定的超時時間 (2)cron屬性規定的時間比緩存信息的開始時間更晚 (3)標簽中緩存的內容在緩存後又被重新刷新過 (4)其他緩存超期設定 如果符合上面四項中的任何一項,被緩存的內容視為已經失效,這時被緩存的內容將被重新處理並且返回處理過後的信息,如果被緩存的內容沒有失效,那麽返回給用戶的將是緩存中的信息。 cache標簽的常用屬性說明: key 標識緩存內容的關鍵詞。在指定的作用範圍內必須是唯一的。默認的key是被訪問頁面的URI和後面的請求字符串。可以在同一個頁面中使用很多cache標簽而不指定他的key屬性,這種情況下系統使用該頁面的URI和後面的請求字符串,另外再自動給這些key增加一個索引值來區分這些緩存內容。但是不推薦采用這樣的方式。 scope 緩存發生作用的範圍,可以是application或者session。默認為application。 time 緩存內容的時間段,單位是秒,默認是3600秒,也就是一個小時,如果設定一個負值,那麽這部分被緩存的內容將永遠不過期。 duration 指定緩存內容失效的時間,是相對time的另一個選擇,可以使用簡單日期格式或者符合USO-8601的日期格式。如:duration=‘PT5M‘ duration=‘5s‘等。 cron 指定緩存內容失效表達式,見“Cron表達式基本語法”。 refresh false 或者true。如果refresh屬性設置為true,不管其他的屬性是否符合條件,這部分被緩存的內容都將被更新,這給編程者一種選擇,決定什麽時候必須刷新。 mode 如果不希望被緩存的內容增加到給用戶的響應中,可以設置mode屬性為"silent"。此時被緩存的部分不在頁面上顯示,而其它任意的mode屬性值都會將緩存的部分顯示到頁面上。 groups 指定當前cache標簽所屬的組,可使用“,”分割組名。這樣就可以對緩存項進行分組了。如果緩存項依賴於應用的其它部分或其它數據,分組就有了用武之地——當這種依賴改變時(刷新相關的組),這個組的所有緩存項都將過期。 language 使用ISO-639定義的語言碼來發布不同的緩存內容(under an otherwise identical key)。要在一個多語言網站上同一段JSP代碼不同用戶的參數提供不同的語言時,這個屬性會很有用。 refreshpolicyclass 指定自定義的刷新策略類的全限定類名。這個類繼承自com.opensymphony.oscache.web.WebEntryRefreshPolicy refreshpolicyparam 指定任意需要傳給refreshpolicyclass的參數。如果沒有指定refreshpolicyclass,則這個值不起作用。 這些屬性可以單獨使用,也可以根據需要組合使用。 3、Cron表達式基本語法 通過Cron表達式我們可以很靈活的設置緩存的失效時間,Cron表達式包括5個字段分別為Minute,Hour, DOM(Day Of Month), Month,DOW(Day Of Week)。他們順序地對應了5個位置。當某個位置上的值為*時,表示該位置上的任意時間。另外還提供了指定時間的操作符號"-",",","/",他們分別表示一段時間範圍,具體的時間,以及遞增的時間段。下面是幾個例子說明一下Cron表達式的基本應用: (1) "10/20 * * * *" :因是第一個位置,並且是一個遞增的表達式,所以表達式指定的是每個小時的第10分鐘,第30分鐘,第50分鐘緩存內容失效。 (2) "* 8-18/4 * * *" :指定每天早上8點到晚上6點之間,每4個小時緩存內容失效。 等同於"* 8,12,16 * * *"。 (3) "* * * * 1-5":表示每個星期一到星期五內容失效。 4、Cache標簽實例分析 (1) 最簡單的cache標簽用法。使用默認的關鍵字來標識cache內容,超時時間是默認的3600秒。 <oscache:cache> <% //自己的JSP代碼內容 %> </oscache:cache> (2) 用自己指定的字符串標識緩存內容,並且設定作用範圍為session。 <oscache:cache key="foobar" scope="session"> <% //自己的JSP代碼內容 %> </oscache:cache> (3) 動態設定key值,使用自己指定的time屬性設定緩存內容的超時時間,使用動態refresh值決定是否強制內容刷新。因為OSCache使用key值來標識緩存內容,使用相同的key值將會被認為使用相同的的緩存內容,所以使用動態的key值可以自由的根據不同的角色、不同的要求決定使用不同的緩存內容。 <oscache:cache key="<%= product.getId() %>" time="1800" refresh="<%= needRefresh %>"> <% //自己的JSP代碼內容 %> </oscache:cache> (4) 設置time屬性為負數使緩存內容永不過期 <oscache:cache time="-1"> <% //自己的JSP代碼內容 %> </oscache:cache> (5) 使用duration屬性設置超期時間 <oscache:cache duration=‘PT5M‘> <% //自己的JSP代碼內容 %> </oscache:cache> (6) 使用mode屬性使被緩存的內容不加入給客戶的響應中 <oscache:cache mode=‘silent‘> <% //自己的JSP代碼內容 %> </oscache:cache> 5、flush標簽 這個標簽用於在運行時刷新緩存。只有運行flush標簽後再次訪問相關緩存項時才執行刷新。 屬性說明: scope[all] 指定要刷新的範圍。可選的值是"application", "session" 和 nul。null(到底是null量還是all呀)值指定刷新所有的緩存(是指使用cache標簽的緩存)。 key 當指定了scope和key值時,刷新唯一的緩存項。當這個緩存項下次被訪問時將被刷新。只指定一個key值而沒有指定scope不起作用。 group 指定一個組時將刷新所有這個組中的緩存項。只指定一個group值而沒有指定scope不起作用。 pattern 任意包含pattern屬性指定的值的緩存項都將被刷新。只指定一個pattern值而沒有指定scope不起作用。 (註意:OSCache項目組已經不贊成使用pattern這個屬性賴刷新緩存,二是鼓勵使用具有更好的靈活性和性能的group屬性來代替) language 使用ISO-639定義的語言碼來發布不同的緩存內容(under an otherwise identical key)。要在一個多語言網站上同一段JSP代碼不同用戶的參數提供不同的語言時,這個屬性會很有用。 6、usecached標簽 <usecached />:必須嵌套在<cache>標簽中。 屬性說明: use 告訴所在的<cache>標簽是否使用已經緩存的內容(缺省為true,使用緩存的內容)。可以使用這個標簽來控制緩存。比如使用<frush>標簽刷新某個key的緩存,但可以在必要的地方即使這樣的強制刷新也仍然使用緩存內容而不刷新。 示例代碼如下: <oscache:cache> <% try { %> ... some jsp content ... <% } catch (Exception e) { %> <cache:usecached /> <% } %> </oscache:cache> 7、addgroup標簽 <addgroup />:必須嵌套在<cache>標簽中。It allows groups to be dynamically added to a cached block. It is useful when the group(s) a cached block should belong to are unknown until the block is actually rendered. As each group is ‘discovered‘, this tag can be used to add the group to the block‘s group list. 屬性說明: group- req The name of the group to add the enclosing cache block to. 示例代碼如下: <oscache:cache key="test1"> <oscache:addgroup group="group1" /> ... some jsp content ... <oscache:addgroup group="group2" /> ... some more jsp content ... </oscache:cache> 8、使用標簽的特殊說明 (1) 標簽的屬性值如果動態生成,則需要先把動態生成的值賦予一個變量,再使用JSP 表達式把動態值賦予對應的屬性。 <!--正確的寫法:--> <% String keyValue = (String)request.getAttribute("keyValue"); if(keyValue == null) keyValue = ""; %> <oscache:cache refresh=‘<%=keyValue%>‘>……</ oscache:cache > <!--不正確的寫法:--> <oscache:cache refresh=‘<%=(String)request.getAttribute("keyValue")%>‘> <!-屬性的值此時為字符串“<%=(String)request.getAttribute("keyValue")%>”---> </ oscache:cache > (2) 標簽的屬性值對boolean是強類型的,比如cache的refresh屬性要求為true或false,示例如下: <!--正確的寫法:--> <oscache:cache refresh=‘true‘>……</ oscache:cache > <!--正確的寫法:--> <% String needRefresh = (String)application.getAttribute("needRefresh"); if(needRefresh == null) needRefresh = "false"; boolean t_f = Boolean.valueOf(needRefresh).booleanValue(); %> <oscache:cache refresh=‘<%=t_f %>‘>……</ oscache:cache > <!--不正確的寫法:--> <oscache:cache refresh=‘<%= needRefresh %>‘>……</ oscache:cache >

用OSCache進行緩存對象