【Java EE 學習 78 上】【數據採集系統第十天】【Service使用Spring緩存模塊】

1、需求分析

  調查問卷中或許每個單擊動做都會引起大量的數據庫訪問,特別是在參與調查的過程當中,只是單擊「上一頁」或者「下一頁」的按鈕就會引起大量的查詢,必須對這種問題進行優化才行。使用緩存策略進行查詢緩存是下降數據庫壓力很是理想的方法,這裏最起碼可以有兩種緩存方式:java

  1.使用hibernate的二級緩存。spring

  2.使用spring自帶的緩存模塊進行查詢緩存。使用spring自帶的緩存模塊功能必需要知足一下條件:數據庫

    (1)spring版本必須至少在3.1或以上,這裏使用了spring3.1express

    (2)必需要使用第三方緩存廠商的緩存支持,這裏使用ehcacheapache

  這裏使用spring自帶的緩存模塊進行查詢緩存。緩存

2、集成spring的緩存模塊實現對Service緩存代理,下降數據庫壓力

  1.引入類庫

    [spring功能模塊]app

    spring-modules-cache.jar  eclipse

    [第三方緩存供應商] ide

    backport-util-concurrent.jar
    com.springsource.org.apache.commons.logging-1.1.1.jar
    ehcache-1.5.0.jar
    jsr107cache-1.1.jar測試

  2.配置ehcache.xml配置文件,指定緩存的過時策略

 1 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 2     <diskStore path="java.io.tmpdir"/>
 3     <defaultCache  4             maxElementsInMemory="10000"
 5  eternal="false"
 6  timeToIdleSeconds="120"
 7  timeToLiveSeconds="120"
 8  overflowToDisk="true"
 9  maxElementsOnDisk="10000000"
10  diskPersistent="false"
11  diskExpiryThreadIntervalSeconds="120"
12  memoryStoreEvictionPolicy="LRU"
13             />
14     <!-- 自定義一個緩存策略 -->
15     <cache name="surveyCache"
16  maxElementsInMemory="10000"
17  eternal="false"
18  timeToIdleSeconds="120"
19  timeToLiveSeconds="120"
20  overflowToDisk="true"
21  maxElementsOnDisk="10000000"
22  diskPersistent="false"
23  diskExpiryThreadIntervalSeconds="120"
24  memoryStoreEvictionPolicy="LRU"
25             />
26 </ehcache>

    上面配置中的屬性意思都比較簡單,很容易理解,不贅述。

  3.經過配置文件配置spring的緩存模塊

    首先,必須必須引入緩存的命名空間才行,因爲eclipse中並無自帶該命名空間相關信息,因此須要外部引入xsd約束,引入方式:

    Window->preferences->XML->XML catalog->Add找到spring-cache-3.1.xsd文件添加進來便可,因爲對應的location已經失效,因此建議使用本地文件協議file:///替代http協議。

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/aop file:///D:\程序\java\Spring\spring-framework-4.2.1\spring-framework-4.2.1.RELEASE\schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/beans file:///D:\程序\java\Spring\spring-framework-4.2.1\spring-framework-4.2.1.RELEASE\schema/beans/spring-beans-2.5.xsd  http://www.springframework.org/schema/cache file:///D:\程序\java\Spring\spring-framework-4.2.1\spring-framework-4.2.1.RELEASE\schema\cache/spring-cache-3.1.xsd http://www.springframework.org/schema/tx file:///D:\程序\java\Spring\spring-framework-4.2.1\spring-framework-4.2.1.RELEASE\schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/context file:///D:\程序\java\Spring\spring-framework-4.2.1\spring-framework-4.2.1.RELEASE\schema/context/spring-context-2.5.xsd">

  (1)ehcache工廠配置

1 <!-- ehcacheManager工廠配置 -->
2 <bean id="ehcacheManager"
3  class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
4     <property name="configLocation" value="classpath:ehcache.xml"></property>
5 </bean>

  (2)ehcache管理器配置

1 <!-- ehcache管理器 -->
2 <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
3     <property name="cacheManager" ref="ehcacheManager"></property>
4 </bean>

  (3)配置key生成器,這裏須要自定義一個key生成器類,先存檔,以後詳解

<!-- Key生成器 ,先存檔 -->
    <bean id="surveyKeyGenerator" class="com.kdyzm.cache.SurveykeyGenerator" />

  (4)定義緩存通知,該配置的做用就是肯定針對什麼樣的方法進行緩存,針對什麼樣的方法清空緩存。

 1 <!-- 定義緩存通知 -->
 2 <cache:advice id="cacheAdvice" cache-manager="cacheManager"
 3  key-generator="surveyKeyGenerator"><!-- 這裏須要配置key生成器 -->
 4     <cache:caching cache="surveyCache">
 5         <!-- 設置緩存的方法 -->
 6         <cache:cacheable method="get*" />
 7         <cache:cacheable method="load" />
 8         <cache:cacheable method="find*" />
 9         <cache:cacheable method="is*" />
10 
11         <!-- 設置須要清空緩存的方法 -->
12         <cache:cache-evict method="save*" all-entries="true" />
13         <cache:cache-evict method="update*" all-entries="true" />
14         <cache:cache-evict method="delete*" all-entries="true" />
15         <cache:cache-evict method="batch*" all-entries="true" />
16         <cache:cache-evict method="create*" all-entries="true" />
17         <cache:cache-evict method="new*" all-entries="true" />
18     </cache:caching>
19 </cache:advice>

  (5)配置緩存AOP,建立切入點表達式,肯定緩存對象的範圍

    爲了將緩存通知首先啓動,將其order屬性配置爲0(並非由於0才首先啓動,只是相對於日誌通知和事務通知來講其order屬性值最小)。

 1 <aop:config>
 2     <!-- 日誌切入點 -->
 3     <aop:pointcut  4         expression="(execution(* *..*Service.save*(..))  5  or execution(* *..*Service.update*(..))  6  or execution(* *..*Service.delete*(..))  7  or execution(* *..*Service.batch*(..))  8  or execution(* *..*Service.create*(..))  9  or execution(* *..*Service.new*(..))) and !bean(logService)"
10  id="loggerPointcut" />
11     <aop:pointcut expression="execution(* *..*Service.*(..))"
12  id="txPointcut" />
13     <!-- 必須配置order屬性,使用該屬性能夠改變配置的通知的加載順序,order值越大,優先級越高 必須讓事務的通知放到後面,讓日誌的通知先執行,這樣才能在執行完成日誌的通知後事務確保可以結束。 14  order值越小,優先級越高 爲了解決事務沒有結束的問題,必須同時修改解除綁定的時間 -->
15 <aop:advisor advice-ref="cacheAdvice" 16  pointcut="execution(* com.kdyzm.service.SurveyService.*(..)) or 17  execution(* com.kdyzm.service.PageService.*(..)) or 18  execution(* com.kdyzm.service.QuestionService.*(..)) or 19  execution(* com.kdyzm.service.AnswerService.*(..))" order="0" />
20     <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"
21  order="2" />
22     <aop:aspect id="loggerAspect" ref="logger" order="1">
23         <aop:around method="record" pointcut-ref="loggerPointcut" />
24     </aop:aspect>
25 </aop:config>

  這裏對調查相關的全部Service中的相關方法都進行了代理緩存。

  4.如何自定義key生成器

    配置文件中有一個key生成器的配置,該配置的做用就是根據當前執行的方法環境(方法名、參數列表、類名)計算出來惟一的標識符(key值),若是該標識符已經存在,則緩存管理器就會調用緩存中的數據不然就執行目標方法並將目標方法的查詢結果緩存起來。

 1 package com.kdyzm.cache;  2 
 3 import java.lang.reflect.Method;  4 
 5 import org.springframework.cache.interceptor.KeyGenerator;  6 
 7 /**
 8  * 自定義key生成器  9  * @author kdyzm 10  * 11  */
12 public class SurveykeyGenerator implements KeyGenerator{ 13 
14     //什麼對象調用的什麼方法,參數列表是什麼
15  @Override 16     public Object generate(Object arg0, Method arg1, Object... arg2) { 17         String targetCode=arg0.getClass().getSimpleName()+"["+arg0.hashCode()+"]";    //arg0是類 18         String methodName=arg1.getName();                            //arg1是方法 19         if(arg2!=null){                                       //arg2是參數列表 20             StringBuffer stringBuffer=new StringBuffer(); 21             stringBuffer.append("("); 22             for(int i=0;i<arg2.length;i++){ 23  stringBuffer.append(arg2[i].toString()); 24                 stringBuffer.append(","); 25  } 26             stringBuffer.append(")"); 27             targetCode= targetCode+"."+methodName+stringBuffer.toString(); 28  System.out.println(targetCode); 29             return targetCode; 30  } 31         targetCode= targetCode+"."+methodName+"()"; 32  System.out.println(targetCode); 33         return targetCode; 34  } 35 }

3、測試效果

  1.在主頁上單擊參與調查,查看後臺

  

  清空控制檯,從新單擊一次「參與調查」超連接,再次查看後臺,這時候就會發現沒有SQL語句發出了(手要快,不要超過120秒,以前配置的ehcach.xml配置文件中聲明瞭若是超過120s沒用的話就會清空緩存,因此仍是會發出SQL查詢語句)

  2.測試參與調查的過程當中的緩存效果。

    這裏須要建立多個調查頁,在翻頁的過程當中查看緩存的效果,這裏個人調查1中一共有三頁。

    (1)單擊調查1,依次單擊下一頁,直到最後一頁,觀察控制檯打印,發現不斷地有SQL查詢發出

  

  

    (2)單擊上一頁、直到第一頁,仍是發現不斷的有查詢發出。

    (3)從第一頁單擊「下一頁」直到最後一頁,發現再也不有查詢發出,單擊上一頁仍是沒有發現有SQL語句發出,證實spring緩存配置成功。

  

相關文章
相關標籤/搜索