posts - 156,  comments - 601,  trackbacks - 0

          前言:
            本文檔將講解一下,如何借助Spring Module項(xiàng)目,實(shí)現(xiàn)配置聲明性緩存功能。
           
             聲明式緩存配置有效地將緩存功能從應(yīng)用程序的核心需求中分離出來,解決了上文提及的眾多問題,還帶來了以下優(yōu)點(diǎn):
          • 更明晰的責(zé)任分離。系統(tǒng)中的模塊僅負(fù)責(zé)其核心需求,不再負(fù)責(zé)緩存功能。這將帶來更出色的可追溯性。
          • 更高的模塊化程度。將緩存功能從核心模塊中分離出來減少了重復(fù)代碼(支持“一次且僅一次”原則),并有助于避免代碼混亂。
          • 設(shè)計(jì)決策的后期綁定。使用聲明式緩存,開發(fā)人員可將與緩存實(shí)現(xiàn)和調(diào)優(yōu)有關(guān)的決策制訂延后。開發(fā)人員可將精力集中在應(yīng)用程序的當(dāng)前核心需求上。聲明式配置支持 YAGNI(“you aren't gonna need it”的縮寫,意為“您將不會(huì)需要它)原則,僅在開發(fā)人員確實(shí)需要的時(shí)候才允許他們?yōu)閼?yīng)用程序添加緩存,而且不需要進(jìn)行系統(tǒng)級(jí)的更改。

          說明:
            本檔的配置經(jīng)過本人測(cè)試,都能正確運(yùn)行。
            運(yùn)行環(huán)境: Jdk5.0, Spring-2.5, Spring-modules-0.9, ehcache-1.6.0-beta4.jar

          首先創(chuàng)建一個(gè)StudentService服務(wù)類,本文將對(duì)其所有的以get* 方式命令的方法,進(jìn)行緩存處理。當(dāng)調(diào)用set* 命令時(shí),需要其刪除緩存
          以更做數(shù)據(jù)的更新。 
          源代碼如下:
           1 public class StudentService {
           2 
           3     private String name = "matthew";
           4     
           5     public String getName() {
           6         return name;
           7     }
           8     
           9     public String getName(String salution) {
          10         return salution + " " + name;
          11     }
          12     
          13     public void setName(String name) {
          14         this.name = name;
          15     }
          16     
          17     public void changeNameAndNotTellCache(String name) {
          18         this.name = name;
          19     }
          20 }


          接下來,就是編寫Spring配置文件 context.xml,以實(shí)現(xiàn)根據(jù)上面的要求,進(jìn)行聲明性緩存功能的配置

          Spring的配置內(nèi)容如下:(已加上注釋)
           1 <?xml version="1.0" encoding="UTF-8"?>
           2 <beans xmlns="http://www.springframework.org/schema/beans"
           3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           4     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">
           5 
           6     <!-- Using a EHCache cache manager -->
           7     <bean id="cacheManager"
           8         class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
           9         <!--<property name="cacheManagerName" value="mainCache"/>-->
          10         <property name="configLocation" value="classpath:ehcache.xml" />
          11     </bean>
          12 
          13     <!-- 使用Spring Modules對(duì) EhCache的封裝  -->
          14     <bean id="cacheProviderFacade" class="org.springmodules.cache.provider.ehcache.EhCacheFacade">
          15         <property name="cacheManager" ref="cacheManager" />
          16     </bean>
          17     
          18     <!-- 配置 方法 攔截器  -->
          19     <!-- 緩存攔截器 -->
          20     <bean id="cachingInterceptor"
          21         class="org.springmodules.cache.interceptor.caching.MethodMapCachingInterceptor">
          22         <property name="cacheProviderFacade" ref="cacheProviderFacade" />
          23         <property name="cachingModels"> <!-- 進(jìn)行cache緩存 -->
          24             <props> <!-- 所有StudentService對(duì)象中,以get開頭的方法都將進(jìn)行緩存 -->
          25                 <prop key="StudentService.get*">cacheName=testCache</prop>
          26             </props>
          27         </property>
          28     </bean>
          29     
          30     <!-- 緩存刷新攔截器 -->
          31     <bean id="flushingInterceptor"
          32         class="org.springmodules.cache.interceptor.flush.MethodMapFlushingInterceptor">
          33         <property name="cacheProviderFacade" ref="cacheProviderFacade" />
          34         <property name="flushingModels"><!-- 進(jìn)行cache刷新(清除) -->
          35             <props>
          36                 <prop key="StudentService.set*">cacheNames=testCache</prop>
          37             </props>
          38         </property>
          39     </bean>
          40     
          41     <!-- 配置 基于BeanName規(guī)則的動(dòng)態(tài)代理封裝 -->
          42     <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
          43         <property name="beanNames">
          44             <list>
          45                 <value>studentService</value>
          46             </list>
          47         </property>
          48         <property name="interceptorNames">
          49             <list>
          50                 <value>cachingInterceptor</value>
          51                 <value>flushingInterceptor</value>
          52             </list>
          53         </property>
          54     </bean>
          55 
          56     <bean id="studentService" class="StudentService"></bean>
          57 </beans>

          接下來,為能讓EhCache能正常工作,還得編寫EhCache配置文件 ehcache.xml, 內(nèi)容如下:

           1 <ehcache>
           2     <diskStore path="java.io.tmpdir" />
           3     <defaultCache maxElementsInMemory="10000" eternal="false"
           4         timeToIdleSeconds="2" timeToLiveSeconds="5" overflowToDisk="true"
           5         maxElementsOnDisk="10000000" diskPersistent="false"
           6         diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" />
           7     <cache name="testCache" maxElementsInMemory="10000"
           8         maxElementsOnDisk="1000" eternal="false" overflowToDisk="false"
           9         diskSpoolBufferSizeMB="20" timeToIdleSeconds="60" timeToLiveSeconds="3600"
          10         memoryStoreEvictionPolicy="LFU" />
          11 </ehcache>


          下面將要測(cè)試配置是否能正確工作,編寫一個(gè)測(cè)試類 Test.java內(nèi)容如下:
           1 public class Test {
           2 
           3     /**
           4      * @param args
           5      */
           6     public static void main(String[] args) {
           7         AbstractApplicationContext context;
           8         context = new ClassPathXmlApplicationContext("classpath*:context.xml");
           9         context.start();
          10         
          11         StudentService ss = (StudentService) context.getBean("studentService");
          12 
          13         String name;
          14         System.out.println("第一次訪問,沒有緩存");
          15         name = ss.getName();
          16         System.out.println(name);
          17         name = ss.getName("Mr");
          18         System.out.println(name);
          19         
          20         //use change not changed value
          21         System.out.println("第二次訪問,使用緩存");
          22         ss.changeNameAndNotTellCache("Michael");
          23         name = ss.getName();
          24         System.out.println(name);
          25         
          26         name = ss.getName("Mr");
          27         System.out.println(name);
          28         
          29         //update cache
          30         System.out.println("清除緩存后,再次訪問 ");
          31         ss.setName("Michael");
          32         name = ss.getName();
          33         System.out.println(name);
          34         
          35         name = ss.getName("Mr");
          36         System.out.println(name);
          37         
          38         context.close();
          39     }
          40 
          41 }


          運(yùn)行后的輸出結(jié)果:
          第一次訪問,沒有緩存
          matthew
          Mr matthew
          第二次訪問,使用緩存
          matthew
          Mr matthew
          清除緩存后,再次訪問 
          Michael
          Mr Michael

          從輸出的結(jié)果上來看,緩存的功能已經(jīng)正確啟效。
          本文只是一個(gè)簡(jiǎn)單的示例,希望對(duì)大家有借鑒作用。
          更多的資料,詳見官方文檔 https://springmodules.dev.java.net/.

          Good Luck!
          Yours Matthew!

          posted on 2010-04-22 19:47 x.matthew 閱讀(3300) 評(píng)論(4)  編輯  收藏 所屬分類: Spring|Hibernate|Other framework
          主站蜘蛛池模板: 庆安县| 德昌县| 深州市| 吉林省| 九龙县| 平南县| 化隆| 社会| 徐州市| 永吉县| 法库县| 二连浩特市| 乌兰县| 庆阳市| 万山特区| 永川市| 郁南县| 海盐县| 江华| 青川县| 靖宇县| 个旧市| 望城县| 通化县| 仁寿县| 龙门县| 台山市| 肥城市| 扎鲁特旗| 峨山| 榕江县| 平遥县| 万年县| 永胜县| 旬邑县| 石嘴山市| 汤原县| 阜宁县| 宜兴市| 天镇县| 大城县|