天天看點

spring 和 ehcache的整合

緩存 SpringModules Cache ( spring 和 ehcache的整合 ) spring提供緩存bean方案 收藏

引自:<SPRING IN ACTION 2>

      Spring程式有一種更優雅的緩存解決方案。Spring Modules項目(http://springmodules.dev.java.net)通過切面提供了緩存,它把通知應用于Bean方法來透明地對其結果進行緩存,而不是明确地指定要被緩存的方法。

     Spring Modules對于緩存的支援涉及到一個代理,它攔截對Spring管理的Bean一個或多個的調用。當一個被代理的方法被調用時,Spring Modules Cache首先查閱一個緩存來判斷這個方法是否已經被使用同樣參數調用過,如果是,它會傳回緩存裡的值,實際的方法并不會被調用;否則,實際方法會被調用,其傳回值會被儲存到緩存裡,以備方法下一次被調用時使用。

     雖然Spring Modules會提供一個代理來攔截方法并把結果儲存到緩存,它并沒有提供一個實際的緩存解決方案,而是要依賴于第三方的緩存方案。可以使用的方案有多個,包括:

 EHCache

 GigaSpaces

 JBoss Cache

 JCS

 OpenSymphony 的 OSCache

 Tangosol 的 Coherence

 我們為RoadRantz程式選擇EHCache,主要是因為我以前使用它的經驗及能夠從www.ibibio.org的Maven倉庫輕易獲得。無論使用哪個緩存方案,對于Spring Modules Cache的配置基本上都是一樣的。

  首先要做的是建立一個Spring配置檔案來聲明緩存。雖然可以把Spring Modules Cache配置放到RoadRantz程式加載的任意一個Spring上下文配置檔案裡,但最好還是把他們分開,是以我們要建立roadrantz-cache.xml來儲存緩存的配置。

  與Spring上下文配置檔案一樣,randrantz-cache.xml也以<beans>元素為根。但為了利用Spring Modules 對EHCache的支援,我們要讓<beans>元素能夠識别ehcache命名空間:

  <?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

  xmlns:jee="http://www.springframework.org/schema/jee"

  xmlns:ehcache="http://www.springframework.org/schema/ehcache"

 xsi:schemaLocation="http://www.springframework.org/schema/beans

           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

           http://www.springframework.org/schema/context

           http://www.springframework.org/schema/context/spring-context-2.5.xsd

           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd

            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd 

            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd 

            http://www.springframework.org/schema/ehcache  http://www.springframework.org/schema/cache/springmodules-ehcache.xsd">

  我們為RoadRantz程式選擇的是EhCache,如果想使用其他緩存方案,需要把Spring Modules命名究竟和規劃聲明修改為相應的内容。

  URI和規劃URI

 命名空間  命名空間URI  規劃URI

 ehcache  http://www.springframework.org/schema/ehcache  http://www.springframework.org/schema/cache/springmodules-ehcache.xsd

 gigaspaces  http://www.springframework.org/schema/gigaspaces  http://www.springframework.org/schema/springmodules-gigaspaces.xsd

 jboss  http://www.springframework.org/schema/jboss  http://www.springframework.org/schema/springmodules-jboss.xsd

 jcs  http://www.springframework.org/schema/jcs  http://www.springframework.org/schema/springmodules-jcs.xsd

 oscache  http://www.springframework.org/schema/oscache  http://www.springframework.org/schema/springmodules-oscache.xsd

 tangosol  http://www.springframework.org/schema/tangosol  http://www.springframework.org/schema/springmodules-tangosol.xsd

  無論選擇哪種緩存,都可以使用一些Spring配置元素在Sping裡對緩存進行配置。

Spring Modules的配置元素

 配置元素  用途

 <namespace:annotations>  以Java5注解來聲明被緩存的方式

 <namespace:commons-attributes>  以Jakarta通用屬性元素資料來聲明被緩存的方式

<namespace:config>  在Spring XML裡配置緩存方案 

<namespace:proxy>  在Spring XML裡聲明一個代理來聲明被緩存的方式 

 在使用EHCache作為緩存方案時,需要告訴Spring到哪裡尋找EHCache配置檔案,這正是<ehcache:config>元素的用途所在:

<ehcache:config configLocation="classpath:ehcache.xml">

在此對configLocation屬性的設定告訴Spring從程式類路徑的根位置加載EHCache的配置。

配置EHCache

<ehcache>

    <!-- Sets the path to the directory where cache .data files are created.

         If the path is a Java System Property it is replaced by

         its value in the running VM.

         The following properties are translated:

         user.home - User's home directory

         user.dir - User's current working directory

         java.io.tmpdir - Default temp file path -->

    <diskStore path="java.io.tmpdir"/>

    <!--Default Cache configuration. These will applied to caches programmatically created through

        the CacheManager.

        The following attributes are required for defaultCache:

        maxInMemory       - Sets the maximum number of objects that will be created in memory

        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element

                            is never expired.

        timeToIdleSeconds - Sets the time to idle for an element before it expires.

                            i.e. The maximum amount of time between accesses before an element expires

                            Is only used if the element is not eternal.

                            Optional attribute. A value of 0 means that an Element can idle for infinity

        timeToLiveSeconds - Sets the time to live for an element before it expires.

                            i.e. The maximum time between creation time and when an element expires.

                            Is only used if the element is not eternal.

        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache

                            has reached the maxInMemory limit.

        -->

    <defaultCache

        maxElementsInMemory="10000"

        eternal="false"

        timeToIdleSeconds="120"

        timeToLiveSeconds="120"

        overflowToDisk="true"

        />

    <cache name="rantzCache"

        maxElementsInMemory="300"

        eternal="false"

        timeToIdleSeconds="500"

        timeToLiveSeconds="500"

        overflowToDisk="true"

        />

</ehcache>

<defulatCache>元素是必須的,描述了在沒有找到其他緩存情況下所使用的緩存。<cache>緩存定義了另一個緩存,可以在ehcache.xml裡出現0次或多次(每次針對定義的一個緩存)

EHCache的緩存配置屬性

 屬性  用于指定

 diskExpiryThreadIntervalSeconds  磁盤過期線程運作的頻率(以秒為機關),也就是磁盤持久的緩存清理過期項目的頻率(預設是120秒)

 diskPersistent  磁盤緩存在VM重新啟動時是否保持(預設為false)

 eternal 元素是否永恒。如果是永恒的,就永遠不會過期(必須設定) 

maxElementsInMemory  記憶體能夠被緩存的最大元素數量(必須設定) 

memoryStoreEvictionPolicy  當達到maxElementsInMemory時,如何強制進行驅逐。預設使用“最近使用(LRU)”政策,還可以使用“先入先出(FIFO)”和“較少使用(LFU)”政策。(預設是LRU) 

name  緩存的名稱(對于<cache>必須設定) 

 overflowToDisk 當記憶體緩存達到maxElementsInMemory時,是否可以溢出到磁盤(必須設定) 

timeToIdleSeconds  導緻元素過期的通路間接(以秒為機關)。設定為0辨別元素可以永遠空閑(預設值為0) 

timeToLiveSeconds  元素在緩存裡可以存在的時間(以秒為機關)。設定為0辨別元素可以在緩存裡永遠存在而不過期(預設值是0) 

     對于RoadRantz程式,我們配置了一個預設緩存(這是EHCache要求的),還配置了一個名為rantzCache的緩存作為主緩存。兩個緩存都設定為最多可以容納500個元素(不過期),通路頻率最低的元素會被踢出,不允許磁盤溢出。

    在Spring程式上下文裡配置的EHCache之後,就可以聲明哪個Bean和方法應該對結果進行緩存。首先,我們來聲明一個代理來緩存RoadRantz DAO層裡方法的傳回值。

 緩存的代理Bean

 我們已經知道HibernateRantDao裡的getRantsForDay()方法很适合進行緩存。再回到Spring上下文定義,我們要使用<ehcache:proxy>元素把一個代理包裹到HibernateRantDao,進而緩存從getRantsForDay()傳回的全部内容:

<ehcache:proxy id="rantDao" refId="rantDaoTarget">

   <ehcache:caching methodName="getRantsForDay" cacheName="rantzCache"/>

</ehcache:proxy>

<ehcache:caching>元素聲明哪個方法要被攔截、其傳回值要儲存到哪個緩存。本例中,methodName被設定為getRantsForDay(),要使用的緩存是rantzCache。

我們可以根據需要在<ehcache:proxy>裡聲明多個<ehcache:caching>來描述Bean方法的緩存。我們可以讓一個<ehcache:caching>用于所有被緩存的方法,也可以使用通配符為一個<ehcache:caching>元素指定多個方法。比如下面的<ehcache:caching>元素會代理緩存全部名稱由get開頭的方法:

<ehcache:caching method="get*" cacheName="rantzCache"/>

 把資料放到緩存裡隻完成了一半的工作。在經過一段時間之後,緩存裡一定會包含大量資料,其中很多沒有意義的資料。最後,這些資料應該被清理,資料緩存周期重新開始。

 重新整理緩存

 <ehcache:caching>元素聲明的是要向緩存中添加資料的方法,而<ehcache:fluching>元素聲明了會清空緩存的方法。舉例來說,假設我們想在saveRant()方法被調用時清空rantzCache緩存,那麼就應該使用如下的<ehcache:flushing>元素:

<ehcache:flushing methodName="saveRant" cacheName="rantzCache"/>

在預設情況下,cacheName屬性裡指定的緩存會在methodName被調用之後清空,但利用when屬性可以指定清空的時機:

<ehcache:flushing methodName="saveRant" cacheName="rantzCache" when="before"/>

把when屬性設定為before可以讓緩存在saveRant()被調用之前清空。

聲明一個被代替的内部Bean

 注意<ehcache:proxy>的id和refld屬性。由<ehcache:proxy>生成的代理的id是rantDao,然後這是HibernateRantDao Bean的id,是以,我們需要把這個真正的Bean重命名為rantDaoTarget。

如果覺得id/refId組合有些奇怪,我們還可以把目标Bean聲明為<ehcache:proxy>的内部Bean:

<ehcache:proxy id="rantDao">

<bean class="....">

<property name="sessionFactory" ref="sessionFactory"/>

</bean>

<ehcahe:caching methodName="getRantsForDay" cacheName="rantzCache"/>

</ehcache:proxy>

即使使用了内部Bean,我們仍然需要為每個要代理的Bean聲明一個<ehcache:proxy>元素,為方法聲明一個或多個<ehcache:caching>元素。

這個東東對我最大的吸引是,不再像以前,緊緊是hibernate對ehcache的支援了。也就是說,現在不論我用任何形式,我隻是針對service或者Dao進行緩存就OK了。更易用

Demo1:

view plaincopy to clipboardprint?

01.<?xml version="1.0" encoding="UTF-8"?>     

02.<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">     

03.<beans>     

04.    <!-- 引用ehCache的配置 -->     

05.    <bean id="defaultCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">     

06.      <property name="configLocation">     

07.        <value>ehcache.xml</value>     

08.      </property>     

09.    </bean>     

10.         

11.    <!-- 定義ehCache的工廠,并設定所使用的Cache name -->     

12.    <bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">     

13.      <property name="cacheManager">     

14.        <ref local="defaultCacheManager"/>     

15.      </property>     

16.      <property name="cacheName">     

17.          <value>DEFAULT_CACHE</value>     

18.      </property>     

19.    </bean>     

20.    

21.    <!-- find/create cache攔截器 -->     

22.    <bean id="methodCacheInterceptor" class="com.co.cache.ehcache.MethodCacheInterceptor">     

23.      <property name="cache">     

24.        <ref local="ehCache" />     

25.      </property>     

26.    </bean>     

27.    <!-- flush cache攔截器 -->     

28.    <bean id="methodCacheAfterAdvice" class="com.co.cache.ehcache.MethodCacheAfterAdvice">     

29.      <property name="cache">     

30.        <ref local="ehCache" />     

31.      </property>     

32.    </bean>     

33.         

34.    <bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">     

35.      <property name="advice">     

36.        <ref local="methodCacheInterceptor"/>     

37.      </property>     

38.      <property name="patterns">     

39.        <list>     

40.            <value>.*find.*</value>     

41.            <value>.*get.*</value>     

42.        </list>     

43.      </property>     

44.    </bean>     

45.    <bean id="methodCachePointCutAdvice" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">     

46.      <property name="advice">     

47.        <ref local="methodCacheAfterAdvice"/>     

48.      </property>     

49.      <property name="patterns">     

50.        <list>     

51.          <value>.*create.*</value>     

52.          <value>.*update.*</value>     

53.          <value>.*delete.*</value>     

54.        </list>     

55.      </property>     

56.    </bean>     

57.</beans>   

<?xml version="1.0" encoding="UTF-8"?>  

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">  

<beans>  

    <!-- 引用ehCache的配置 -->  

    <bean id="defaultCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">  

      <property name="configLocation">  

        <value>ehcache.xml</value>  

      </property>  

    </bean>  

    <!-- 定義ehCache的工廠,并設定所使用的Cache name -->  

    <bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">  

      <property name="cacheManager">  

        <ref local="defaultCacheManager"/>  

      </property>  

      <property name="cacheName">  

          <value>DEFAULT_CACHE</value>  

      </property>  

    </bean>  

    <!-- find/create cache攔截器 -->  

    <bean id="methodCacheInterceptor" class="com.co.cache.ehcache.MethodCacheInterceptor">  

      <property name="cache">  

        <ref local="ehCache" />  

      </property>  

    </bean>  

    <!-- flush cache攔截器 -->  

    <bean id="methodCacheAfterAdvice" class="com.co.cache.ehcache.MethodCacheAfterAdvice">  

      <property name="cache">  

        <ref local="ehCache" />  

      </property>  

    </bean>  

    <bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">  

      <property name="advice">  

        <ref local="methodCacheInterceptor"/>  

      </property>  

      <property name="patterns">  

        <list>  

            <value>.*find.*</value>  

            <value>.*get.*</value>  

        </list>  

      </property>  

    </bean>  

    <bean id="methodCachePointCutAdvice" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">  

      <property name="advice">  

        <ref local="methodCacheAfterAdvice"/>  

      </property>  

      <property name="patterns">  

        <list>  

          <value>.*create.*</value>  

          <value>.*update.*</value>  

          <value>.*delete.*</value>  

        </list>  

      </property>  

    </bean>  

</beans> 

Demo2:

建立配置檔案:

ehcache2.xml

view plaincopy to clipboardprint?

01.<ehcache> 

02.    <!-- Sets the path to the directory where cache .data files are created.  

03.         If the path is a Java System Property it is replaced by  

04.         its value in the running VM.  

05.         The following properties are translated:  

06.         user.home - User's home directory  

07.         user.dir - User's current working directory  

08.         java.io.tmpdir - Default temp file path --> 

09.    <diskStore path="java.io.tmpdir"/> 

10. 

11.    <!--Default Cache configuration. These will applied to caches programmatically created through  

12.        the CacheManager.  

13.        The following attributes are required for defaultCache:  

14.        maxInMemory       - Sets the maximum number of objects that will be created in memory  

15.        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element  

16.                            is never expired.  

17.        timeToIdleSeconds - Sets the time to idle for an element before it expires.  

18.                            i.e. The maximum amount of time between accesses before an element expires  

19.                            Is only used if the element is not eternal.  

20.                            Optional attribute. A value of 0 means that an Element can idle for infinity  

21.        timeToLiveSeconds - Sets the time to live for an element before it expires.  

22.                            i.e. The maximum time between creation time and when an element expires.  

23.                            Is only used if the element is not eternal.  

24.        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache  

25.                            has reached the maxInMemory limit.  

26.        --> 

27.    <defaultCache 

28.        maxElementsInMemory="10000" 

29.        eternal="false" 

30.        timeToIdleSeconds="120" 

31.        timeToLiveSeconds="120" 

32.        overflowToDisk="true" 

33.        /> 

34.          

35.    <cache name="myCache1" 

36.        maxElementsInMemory="300" 

37.        eternal="false" 

38.        timeToIdleSeconds="500" 

39.        timeToLiveSeconds="500" 

40.        overflowToDisk="true" 

41.        /> 

42.          

43.</ehcache> 

<ehcache>

    <!-- Sets the path to the directory where cache .data files are created.

         If the path is a Java System Property it is replaced by

         its value in the running VM.

         The following properties are translated:

         user.home - User's home directory

         user.dir - User's current working directory

         java.io.tmpdir - Default temp file path -->

    <diskStore path="java.io.tmpdir"/>

    <!--Default Cache configuration. These will applied to caches programmatically created through

        the CacheManager.

        The following attributes are required for defaultCache:

        maxInMemory       - Sets the maximum number of objects that will be created in memory

        eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element

                            is never expired.

        timeToIdleSeconds - Sets the time to idle for an element before it expires.

                            i.e. The maximum amount of time between accesses before an element expires

                            Is only used if the element is not eternal.

                            Optional attribute. A value of 0 means that an Element can idle for infinity

        timeToLiveSeconds - Sets the time to live for an element before it expires.

                            i.e. The maximum time between creation time and when an element expires.

                            Is only used if the element is not eternal.

        overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache

                            has reached the maxInMemory limit.

        -->

    <defaultCache

        maxElementsInMemory="10000"

        eternal="false"

        timeToIdleSeconds="120"

        timeToLiveSeconds="120"

        overflowToDisk="true"

        />

    <cache name="myCache1"

        maxElementsInMemory="300"

        eternal="false"

        timeToIdleSeconds="500"

        timeToLiveSeconds="500"

        overflowToDisk="true"

        />

</ehcache>

 bean-jdbc.xml

view plaincopy to clipboardprint?

01.<?xml version="1.0" encoding="UTF-8"?> 

02.<beans xmlns="http://www.springframework.org/schema/beans" 

03.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 

04.    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 

05.     xmlns:jee="http://www.springframework.org/schema/jee"   

06.    xsi:schemaLocation="http://www.springframework.org/schema/beans  

07.           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  

08.           http://www.springframework.org/schema/context  

09.           http://www.springframework.org/schema/context/spring-context-2.5.xsd  

10.           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd   

11.            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd    

12.            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> 

13.    <context:property-placeholder location="classpath:jdbc_config.properties"/> 

14.    <!--   

15.        DriverManagerDataSource:在每個連接配接請求時建立一個連接配接。  

16.        SingleConnectionDataSource:在每個連接配接請求時都傳回同一連接配接。  

17.     --> 

18.    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 

19.        <property name="driverClassName" value="${driverClassName}"/> 

20.        <property name="url" value="${url}"/> 

21.        <property name="username" value="${username}"/> 

22.        <property name="password" value="${password}"/> 

23.    </bean>   

24.</beans>   

25.  

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

  xmlns:jee="http://www.springframework.org/schema/jee"

 xsi:schemaLocation="http://www.springframework.org/schema/beans

           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

           http://www.springframework.org/schema/context

           http://www.springframework.org/schema/context/spring-context-2.5.xsd

           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd

            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd 

            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

 <context:property-placeholder location="classpath:jdbc_config.properties"/>

 <!--

  DriverManagerDataSource:在每個連接配接請求時建立一個連接配接。

  SingleConnectionDataSource:在每個連接配接請求時都傳回同一連接配接。

  -->

 <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">

  <property name="driverClassName" value="${driverClassName}"/>

  <property name="url" value="${url}"/>

  <property name="username" value="${username}"/>

  <property name="password" value="${password}"/>

 </bean>

</beans>

 beans-jdbc.xml

view plaincopy to clipboardprint?

01.<?xml version="1.0" encoding="UTF-8"?> 

02.<beans xmlns="http://www.springframework.org/schema/beans" 

03.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" 

04.    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 

05.     xmlns:jee="http://www.springframework.org/schema/jee"   

06.     xmlns:ehcache="http://www.springmodules.org/schema/ehcache" 

07.    xsi:schemaLocation="http://www.springframework.org/schema/beans   

08.           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd    

09.           http://www.springframework.org/schema/context    

10.           http://www.springframework.org/schema/context/spring-context-2.5.xsd    

11.           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd    

12.            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd    

13.            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd    

14.            http://www.springmodules.org/schema/ehcache  http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd"    

15.            default-autowire="byName"> 

16.    <import  resource="classpath:bean-jdbc.xml" /> 

17.    <!-- ehcache的各種配置政策 --> 

18.    <ehcache:config configLocation="classpath:ehcache2.xml"/> 

19.      

20.    <!--    

21.    <bean id="userManageService" class="cn.partner4java.ehcache.service.impl.UserManageServiceBean"></bean> 

22.    <ehcache:proxy id="userManageServicePro" refId="userManageService"> 

23.        <ehcache:caching methodName="query*" cacheName="myCache1"/> 

24.        <ehcache:flushing methodName="save" cacheNames="myCache1" when="before"/> 

25.        <ehcache:flushing methodName="delete*" cacheNames="myCache1"/> 

26.    </ehcache:proxy> 

27.    --> 

28.      

29.    <!-- 聲明緩存政策: cacheName屬性裡指定的緩存會在methodName被調用之後清空,但是利用when屬性可以指定清空的時機 --> 

30.    <ehcache:proxy id="userManageService"> 

31.        <bean class="cn.partner4java.ehcache.service.impl.UserManageServiceBean"></bean> 

32.        <ehcache:caching methodName="query*" cacheName="myCache1"/> 

33.        <ehcache:flushing methodName="save" cacheNames="myCache1" when="before"/> 

34.        <ehcache:flushing methodName="delete*" cacheNames="myCache1"/> 

35.    </ehcache:proxy> 

36.      

37.    <!-- 注解形式  

38.    <ehcache:annotations> 

39.        <ehcache:caching cacheName="myCache1" id="cacheModel"/> 

40.        <ehcache:flushing cacheNames="myCache1" id="flushModel" when="before"/> 

41.    </ehcache:annotations> 

42.    --> 

43.      

44.</beans>   

45.  

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"

 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"

  xmlns:jee="http://www.springframework.org/schema/jee"

  xmlns:ehcache="http://www.springmodules.org/schema/ehcache"

 xsi:schemaLocation="http://www.springframework.org/schema/beans

           http://www.springframework.org/schema/beans/spring-beans-2.5.xsd 

           http://www.springframework.org/schema/context 

           http://www.springframework.org/schema/context/spring-context-2.5.xsd 

           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd 

            http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd 

            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd 

            http://www.springmodules.org/schema/ehcache  http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd" 

            default-autowire="byName">

 <import resource="classpath:bean-jdbc.xml" />

 <!-- ehcache的各種配置政策 -->

 <ehcache:config configLocation="classpath:ehcache2.xml"/>

 <!-- 

 <bean id="userManageService" class="cn.partner4java.ehcache.service.impl.UserManageServiceBean"></bean>

 <ehcache:proxy id="userManageServicePro" refId="userManageService">

  <ehcache:caching methodName="query*" cacheName="myCache1"/>

  <ehcache:flushing methodName="save" cacheNames="myCache1" when="before"/>

  <ehcache:flushing methodName="delete*" cacheNames="myCache1"/>

 </ehcache:proxy>

 -->

 <!-- 聲明緩存政策: cacheName屬性裡指定的緩存會在methodName被調用之後清空,但是利用when屬性可以指定清空的時機 -->

 <ehcache:proxy id="userManageService">

  <bean class="cn.partner4java.ehcache.service.impl.UserManageServiceBean"></bean>

  <ehcache:caching methodName="query*" cacheName="myCache1"/>

  <ehcache:flushing methodName="save" cacheNames="myCache1" when="before"/>

  <ehcache:flushing methodName="delete*" cacheNames="myCache1"/>

 </ehcache:proxy>

 <!-- 注解形式

 <ehcache:annotations>

  <ehcache:caching cacheName="myCache1" id="cacheModel"/>

  <ehcache:flushing cacheNames="myCache1" id="flushModel" when="before"/>

 </ehcache:annotations>

 -->

</beans>

 一個使用者我後面單元測試的基礎類:

view plaincopy to clipboardprint?

01.package cn.partner4java.utils;  

02.import org.springframework.context.ApplicationContext;  

03.import org.springframework.context.support.ClassPathXmlApplicationContext;  

04. 

10.public class SpringContextFactory {  

11.    private SpringContextFactory() {  

12.    }  

13.    private static ApplicationContext ac = new ClassPathXmlApplicationContext(  

14.            new String[] { "beans-jdbc.xml" });  

15.    private static SpringContextFactory springContextFactory;  

16.    public static SpringContextFactory getSpringContextFactory() {  

17.        if (springContextFactory == null) {  

18.            springContextFactory = new SpringContextFactory();  

19.        }  

20.        return springContextFactory;  

21.    }  

22.    public static ApplicationContext getApplicationContext() {  

23.        return getSpringContextFactory().ac;  

24.    }  

25.     

30.    public static Object getBean(String beanName) {  

31.        return getApplicationContext().getBean(beanName);  

32.    }  

33.} 

package cn.partner4java.utils;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringContextFactory {

 private SpringContextFactory() {

 }

 private static ApplicationContext ac = new ClassPathXmlApplicationContext(

   new String[] { "beans-jdbc.xml" });

 private static SpringContextFactory springContextFactory;

 public static SpringContextFactory getSpringContextFactory() {

  if (springContextFactory == null) {

   springContextFactory = new SpringContextFactory();

  }

  return springContextFactory;

 }

 public static ApplicationContext getApplicationContext() {

  return getSpringContextFactory().ac;

 }

 public static Object getBean(String beanName) {

  return getApplicationContext().getBean(beanName);

 }

}

我的實體bean:

view plaincopy to clipboardprint?

01.package cn.partner4java.ehcache.bean;  

02.import java.io.Serializable;  

03. 

08.public class User implements Serializable {  

09.    private int id;  

10.    private String userName;  

11.    private String password;  

12.    public User() {  

13.        super();  

14.    }  

15.      

16.    public User(String userName, String password) {  

17.        super();  

18.        this.userName = userName;  

19.        this.password = password;  

20.    }  

21.    public User(int id, String userName, String password) {  

22.        super();  

23.        this.id = id;  

24.        this.userName = userName;  

25.        this.password = password;  

26.    }  

27.    public int getId() {  

28.        return id;  

29.    }  

30.    public void setId(int id) {  

31.        this.id = id;  

32.    }  

33.    public String getUserName() {  

34.        return userName;  

35.    }  

36.    public void setUserName(String userName) {  

37.        this.userName = userName;  

38.    }  

39.    public String getPassword() {  

40.        return password;  

41.    }  

42.    public void setPassword(String password) {  

43.        this.password = password;  

44.    }  

45.    @Override 

46.    public String toString() {  

47.        return "User [id=" + id + ", password=" + password + ", userName=" 

48.                + userName + "]";  

49.    }  

50.    @Override 

51.    public int hashCode() {  

52.        final int prime = 31;  

53.        int result = 1;  

54.        result = prime * result + id;  

55.        return result;  

56.    }  

57.    @Override 

58.    public boolean equals(Object obj) {  

59.        if (this == obj)  

60.            return true;  

61.        if (obj == null)  

62.            return false;  

63.        if (getClass() != obj.getClass())  

64.            return false;  

65.        User other = (User) obj;  

66.        if (id != other.id)  

67.            return false;  

68.        return true;  

69.    }  

70.      

71.      

72.} 

package cn.partner4java.ehcache.bean;

import java.io.Serializable;

public class User implements Serializable {

 private int id;

 private String userName;

 private String password;

 public User() {

  super();

 }

 public User(String userName, String password) {

  super();

  this.userName = userName;

  this.password = password;

 }

 public User(int id, String userName, String password) {

  super();

  this.id = id;

  this.userName = userName;

  this.password = password;

 }

 public int getId() {

  return id;

 }

 public void setId(int id) {

  this.id = id;

 }

 public String getUserName() {

  return userName;

 }

 public void setUserName(String userName) {

  this.userName = userName;

 }

 public String getPassword() {

  return password;

 }

 public void setPassword(String password) {

  this.password = password;

 }

 @Override

 public String toString() {

  return "User [id=" + id + ", password=" + password + ", userName="

    + userName + "]";

 }

 @Override

 public int hashCode() {

  final int prime = 31;

  int result = 1;

  result = prime * result + id;

  return result;

 }

 @Override

 public boolean equals(Object obj) {

  if (this == obj)

   return true;

  if (obj == null)

   return false;

  if (getClass() != obj.getClass())

   return false;

  User other = (User) obj;

  if (id != other.id)

   return false;

  return true;

 }

}

接口:

view plaincopy to clipboardprint?

01.package cn.partner4java.ehcache.service;  

02.import java.util.List;  

03.import cn.partner4java.ehcache.bean.User;  

04. 

09.public interface UserManageService {  

10.    public void save(User user);  

11.    public List<User> queryForList();  

12.    public void deleteById(int id);  

13.} 

package cn.partner4java.ehcache.service;

import java.util.List;

import cn.partner4java.ehcache.bean.User;

public interface UserManageService {

 public void save(User user);

 public List<User> queryForList();

 public void deleteById(int id);

}

實作類:

view plaincopy to clipboardprint?

01.package cn.partner4java.ehcache.service.impl;  

02.import java.sql.ResultSet;  

03.import java.sql.SQLException;  

04.import java.util.HashMap;  

05.import java.util.List;  

06.import java.util.Map;  

07.import org.springframework.jdbc.core.simple.ParameterizedRowMapper;  

08.import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;  

09.import org.springmodules.cache.annotations.CacheFlush;  

10.import org.springmodules.cache.annotations.Cacheable;  

11.import cn.partner4java.ehcache.bean.User;  

12.import cn.partner4java.ehcache.service.UserManageService;  

13. 

18.public class UserManageServiceBean extends SimpleJdbcDaoSupport implements UserManageService {  

19.//  @CacheFlush(modelId="flushModel") //使用注解形式,需要打開配置檔案的注解配置  

20.    public void deleteById(int id) {  

21.        Map parameters = new HashMap();  

22.        parameters.put("id", id);  

23.        this.getSimpleJdbcTemplate().update(USER_DELETE, parameters);  

24.    }  

25.      

26.    private static final String USER_DELETE = "delete from user where id = :id";  

27.//  @Cacheable(modelId="cacheModel")  

28.    public List<User> queryForList() {  

29.        List<User> users = this.getSimpleJdbcTemplate().query(USER_SELECT,   

30.                new ParameterizedRowMapper<User>() {  

31.                    public User mapRow(ResultSet rs, int rowNum) throws SQLException {  

32.                        User user = new User();  

33.                        user.setId(rs.getInt(1));  

34.                        user.setUserName(rs.getString(2));  

35.                        user.setPassword(rs.getString(3));  

36.                        return user;  

37.                    }  

38.        });  

39.        return users;  

40.    }  

41.      

42.    private static final String USER_SELECT = "select id,username,password from user ";  

43.    public void save(User user) {  

44.        Map parameters = new HashMap();  

45.        parameters.put("username", user.getUserName());  

46.        parameters.put("password", user.getPassword());  

47.        this.getSimpleJdbcTemplate().update(USER_INSERT, parameters);  

48.    }  

49.    private static final String USER_INSERT = "insert into user (username,password) values (:username, :password)";  

50.      

51.} 

package cn.partner4java.ehcache.service.impl;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.springframework.jdbc.core.simple.ParameterizedRowMapper;

import org.springframework.jdbc.core.simple.SimpleJdbcDaoSupport;

import org.springmodules.cache.annotations.CacheFlush;

import org.springmodules.cache.annotations.Cacheable;

import cn.partner4java.ehcache.bean.User;

import cn.partner4java.ehcache.service.UserManageService;

public class UserManageServiceBean extends SimpleJdbcDaoSupport implements UserManageService {

// @CacheFlush(modelId="flushModel") //使用注解形式,需要打開配置檔案的注解配置

 public void deleteById(int id) {

  Map parameters = new HashMap();

  parameters.put("id", id);

  this.getSimpleJdbcTemplate().update(USER_DELETE, parameters);

 }

 private static final String USER_DELETE = "delete from user where id = :id";

// @Cacheable(modelId="cacheModel")

 public List<User> queryForList() {

  List<User> users = this.getSimpleJdbcTemplate().query(USER_SELECT,

    new ParameterizedRowMapper<User>() {

     public User mapRow(ResultSet rs, int rowNum) throws SQLException {

      User user = new User();

      user.setId(rs.getInt(1));

      user.setUserName(rs.getString(2));

      user.setPassword(rs.getString(3));

      return user;

     }

  });

  return users;

 }

 private static final String USER_SELECT = "select id,username,password from user ";

 public void save(User user) {

  Map parameters = new HashMap();

  parameters.put("username", user.getUserName());

  parameters.put("password", user.getPassword());

  this.getSimpleJdbcTemplate().update(USER_INSERT, parameters);

 }

 private static final String USER_INSERT = "insert into user (username,password) values (:username, :password)";

}

我一般寫完service,都會先測試一下,我的Junit:

view plaincopy to clipboardprint?

01.package cn.partner4java.ehcache.service.impl;  

02.import java.util.List;  

03.import cn.partner4java.ehcache.bean.User;  

04.import cn.partner4java.ehcache.service.UserManageService;  

05.import cn.partner4java.utils.SpringContextFactory;  

06.import junit.framework.TestCase;  

07.public class UserManageServiceBeanTest extends TestCase {  

08.    private static UserManageService userManageService = (UserManageService) SpringContextFactory.getBean("userManageService");  

09.      

10.    public void testDeleteById() {  

11.        userManageService.deleteById(2);  

12.    }  

13.    public void testQueryForList() {  

14.        List<User> users = userManageService.queryForList();  

15.        System.out.print(users);  

16.    }  

17.    public void testSave() {  

18.        userManageService.save(new User("cache_test", "123"));  

19.    }  

20.} 

package cn.partner4java.ehcache.service.impl;

import java.util.List;

import cn.partner4java.ehcache.bean.User;

import cn.partner4java.ehcache.service.UserManageService;

import cn.partner4java.utils.SpringContextFactory;

import junit.framework.TestCase;

public class UserManageServiceBeanTest extends TestCase {

 private static UserManageService userManageService = (UserManageService) SpringContextFactory.getBean("userManageService");

 public void testDeleteById() {

  userManageService.deleteById(2);

 }

 public void testQueryForList() {

  List<User> users = userManageService.queryForList();

  System.out.print(users);

 }

 public void testSave() {

  userManageService.save(new User("cache_test", "123"));

 }

}

我簡單寫了個jsp測試一下:

view plaincopy to clipboardprint?

01.<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>  

02.<%@page import="cn.partner4java.ehcache.service.UserManageService"%>  

03.<%@page import="cn.partner4java.utils.SpringContextFactory"%>  

04.<%@page import="cn.partner4java.ehcache.bean.User"%>  

05.<%  

06.String path = request.getContextPath();  

07.String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";  

08.%>  

09.<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">  

10.<html>  

11.  <head>  

12.    <base href="<%=basePath%>" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >  

13.      

14.    <title>My JSP 'testCacheList.jsp' starting page</title>  

15.      

16.    <meta http-equiv="pragma" content="no-cache">  

17.    <meta http-equiv="cache-control" content="no-cache">  

18.    <meta http-equiv="expires" content="0">      

19.    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">  

20.    <meta http-equiv="description" content="This is my page">  

21.    <!--  

22.    <link rel="stylesheet" type="text/css" href="styles.css" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" mce_href="styles.css" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >  

23.    -->  

24.  </head>  

25.  <%  

26.    UserManageService userManageService = (UserManageService) SpringContextFactory.getBean("userManageService");  

27.    List<User> users = userManageService.queryForList();  

28.    out.print(users);  

29.   %>  

30.  <body>  

31.    This is my JSP page. <br>  

32.      

33.  </body>  

34.</html> 

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%@page import="cn.partner4java.ehcache.service.UserManageService"%>

<%@page import="cn.partner4java.utils.SpringContextFactory"%>

<%@page import="cn.partner4java.ehcache.bean.User"%>

<%

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

  <head>

    <base href="<%=basePath%>" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >

    <title>My JSP 'testCacheList.jsp' starting page</title>

 <meta http-equiv="pragma" content="no-cache">

 <meta http-equiv="cache-control" content="no-cache">

 <meta http-equiv="expires" content="0">   

 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">

 <meta http-equiv="description" content="This is my page">

 <!--

 <link rel="stylesheet" type="text/css" href="styles.css" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" mce_href="styles.css" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" >

 -->

  </head>

  <%

   UserManageService userManageService = (UserManageService) SpringContextFactory.getBean("userManageService");

   List<User> users = userManageService.queryForList();

   out.print(users);

   %>

  <body>

    This is my JSP page. <br>

  </body>

</html>

但是怎麼測試呢?呵呵,我就是些了一個清單,然後打開,檢視,比如現在十條資料,我打開了一個mysql管理工具,删了幾條資料,重新整理這個界面還是十條資料,沒少。就驗證了緩存這點。

還有另外一種不利用spring支援的xml配置标簽和注解的形式,利用切面程式設計,改天再整理出來,不過,我還是很喜歡這種,是以第一時間就先搞的這個,但是有一點注意的是,包,這個利用的是springmodules項目,是以要單獨引入springmodules相關的ehcahe,的卻難找。還有,ehcache的核心包,和核心包需要的相關包。

spring-modules-cache-0.8.jar

ehcache-core-2.4.0.jar。。。

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/aspectjrt.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/aspectjweaver.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/c3p0-0.9.1.2.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/commons-dbcp-1.2.2.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/commons-logging.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/commons-pool-1.3.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/mysql-connector-java-5.1.7-bin.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/antlr-2.7.6.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/cglib-2.2.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/commons-collections-3.1.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/dom4j-1.6.1.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/hibernate3.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/javassist-3.9.0.GA.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/jta-1.1.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/log4j-1.2.15.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/spring.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/slf4j-api-1.6.1.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/slf4j-jdk14-1.6.1.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/ehcache-core-2.4.0.jar"/>

 <classpathentry kind="lib" path="WebRoot/WEB-INF/lib/spring-modules-cache-0.8.jar"/>

繼續閱讀