zoukankan      html  css  js  c++  java
  • 缓存初解(三)---Spring3.0基于注解的缓存配置+Ehcache和OScache

    本文将构建一个普通工程来说明spring注解缓存的使用方式,关于如何在web应用中使用注解缓存,请参见:

    Spring基于注解的缓存配置--web应用实例

    一.简介
    在spring的modules包中提供对许多第三方缓存方案的支持,包括:
    EHCache
    OSCache(OpenSymphony)
    JCS
    GigaSpaces
    JBoss Cache
    等等。
    将这些第三方缓存方案配置在spring中很简单,网上有许多介绍,这里只重点介绍如何配置基于注解的缓存配置。
    本文将通过例举EHCache和OSCache详细介绍如何使用spring配置基于注解的缓存配置,注意这里的缓存是方法级的。

    二.依赖
    在开始介绍如何进行缓存配置前先介绍一下EHCache和OSCache的jar依赖。
    EHCache:
    ehcache-core-1.7.2.jar
    jakarta-oro-2.0.8.jar
    slf4j-api-1.5.8.jar
    slf4j-jdk14-1.5.8.jar

    OSCache:
    oscache-2.4.1.jar

    此外,两者都需要的jar如下:
    cglib-nodep-2.1_3.jar
    commons-logging.jar
    log4j-1.2.15.jar
    spring-modules-cache.jar
    spring.jar

    三.配置

    两种缓存在spring配置文件中都可以使用两种配置方式,一种是spring2.0以前的完全基于bean的复杂配置,一种是使用后来的基于命名空间的简单配置,两种配置效果相同,分别介绍如下:


    EHCache:
    1)普通配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    	<!-- aop代理,这个是必须地,否则缓存不起作用 -->
    	<bean id="autoproxy"
    		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
    
    	
    	<!-- EhCache 管理工厂 用于指定ehcache配置文件路径 -->
    	<bean id="cacheManager"
    		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
    		<property name="configLocation" value="classpath:ehcache.xml" />
    	</bean>
    	<bean id="cacheProviderFacade" class="org.springmodules.cache.provider.ehcache.EhCacheFacade">
    		<property name="cacheManager" ref="cacheManager" />
    	</bean>
    
    
    	<!-- 1.5+ Annotation 基于注解查找被缓存的业务方法 -->
    	<bean id="cachingAttributeSource"
    		class="org.springmodules.cache.annotations.AnnotationCachingAttributeSource"></bean>
    	<!-- 缓存拦截器:定义了缓存模块,ehcache只需要指定配置文件中的缓存名称 -->
    	<bean id="cachingInterceptor"
    		class="org.springmodules.cache.interceptor.caching.MetadataCachingInterceptor">
    		<property name="cacheProviderFacade" ref="cacheProviderFacade" />
    		<property name="cachingAttributeSource" ref="cachingAttributeSource" />
    		<property name="cachingModels">
    			<props>
    				<prop key="testCaching">cacheName=testCache</prop>
    			</props>
    		</property>
    	</bean>
    
    	<!-- 基于注解查找缓存业务方法的AOP通知器 -->
    	<bean id="cachingAttributeSourceAdvisor"
    		class="org.springmodules.cache.interceptor.caching.CachingAttributeSourceAdvisor">
    		<constructor-arg ref="cachingInterceptor" />
    	</bean>
    
    	<!-- 基于注解查找触发缓存刷新动作的业务方法 -->
    	<bean id="flushingAttributeSource"
    		class="org.springmodules.cache.annotations.AnnotationFlushingAttributeSource"></bean>
    
    	<!-- 刷新拦截器:定义了刷新策略,基于那个模块ID,刷新相应的缓存 -->
     	<bean id="flushingInterceptor"
    		class="org.springmodules.cache.interceptor.flush.MetadataFlushingInterceptor">
    		<property name="cacheProviderFacade" ref="cacheProviderFacade" />
    		<property name="flushingAttributeSource" ref="flushingAttributeSource" />
    		<property name="flushingModels">
    			<map>
    				<entry key="testFlushing">
    					<bean
    						class="org.springmodules.cache.provider.ehcache.EhCacheFlushingModel">
    						
    						<property name="cacheNames">
    							<list>
    								<value>testCache</value>
    							</list>
    						</property>
    						 
    						 <!-- 报错,应该是不能直接设置cacheName
    						 <property name="cacheName" value="testCache"/>			
    						 -->			
    					</bean>
    				</entry>
    			</map>
    
    		</property>
    	</bean>
    
    	<!-- 基于注解查找刷新缓存业务方法的AOP通知器 -->
    	<bean id="flushingAttributeSourceAdvisor"
    		class="org.springmodules.cache.interceptor.flush.FlushingAttributeSourceAdvisor">
    		<constructor-arg ref="flushingInterceptor" />
    	</bean>
    
    	<!-- 测试对象 -->
    	<bean id="testCache" class="com.TestCache"/>
    
    </beans>
    

     2)命名空间配置

    <?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: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.springmodules.org/schema/ehcache http://www.springmodules.org/schema/cache/springmodules-ehcache.xsd">
    
    <!-- 这里可以不需要配置这个
    	<bean id="autoproxy" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
     -->
    	
    	<ehcache:config configLocation="classpath:ehcache.xml"
    		id="cacheProvider" />
    	<ehcache:annotations providerId="cacheProvider">
    		<ehcache:caching cacheName="testCache" id="testCaching" />
    		<ehcache:flushing cacheNames="testCache" id="testFlushing" />
    	</ehcache:annotations>
    	
    	
    	<bean id="testCache" class="com.TestCache"/>	
    
    </beans>
    

     OSCache:
    1)普通配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    	<!-- 这个是必须地,否则缓存不起作用 -->
    	<bean id="autoproxy"
    		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
    
    	<!-- 缓存管理工厂:使用OSCache缓存管理,配置了OSCache使用的配置文件路径 -->
    	<bean id="cacheManager"
    		class="org.springmodules.cache.provider.oscache.OsCacheManagerFactoryBean">
    		<property name="configLocation" value="classpath:oscache.properties" />
    	</bean>
    	<!-- 缓存提供:OSCache -->
    	<bean id="cacheProviderFacade" class="org.springmodules.cache.provider.oscache.OsCacheFacade">
    		<property name="cacheManager" ref="cacheManager" />
    	</bean>
    
    
    
    	<!-- 1.5+ Annotation 基于注解查找被缓存的业务方法 -->
    	<bean id="cachingAttributeSource"
    		class="org.springmodules.cache.annotations.AnnotationCachingAttributeSource"></bean>
    
    	<!-- 缓存拦截器:定义了缓存模块,以及相应的刷新策略,以及缓存所属群组 -->
     	<bean id="cachingInterceptor"
    		class="org.springmodules.cache.interceptor.caching.MetadataCachingInterceptor">
    		<property name="cacheProviderFacade" ref="cacheProviderFacade" />
    		<property name="cachingAttributeSource" ref="cachingAttributeSource" />
    		<property name="cachingModels">
    			<props>
    				<prop key="testCaching">refreshPeriod=86400;cronExpression=0 1 * * *;groups=pb_test</prop>
    			</props>
    		</property>
    	</bean>
    
    	<!-- 基于注解查找缓存业务方法的AOP通知器 -->
    	<bean id="cachingAttributeSourceAdvisor"
    		class="org.springmodules.cache.interceptor.caching.CachingAttributeSourceAdvisor">
    		<constructor-arg ref="cachingInterceptor" />
    	</bean>
    
    	<!-- 基于注解查找触发缓存刷新动作的业务方法 -->
    	<bean id="flushingAttributeSource"
    		class="org.springmodules.cache.annotations.AnnotationFlushingAttributeSource"></bean>
    
    	<!-- 刷新拦截器:定义了刷新策略,基于那个模块ID,刷新相应的缓存群组 -->
    	<bean id="flushingInterceptor"
    		class="org.springmodules.cache.interceptor.flush.MetadataFlushingInterceptor">
    		<property name="cacheProviderFacade" ref="cacheProviderFacade" />
    		<property name="flushingAttributeSource" ref="flushingAttributeSource" />
    		<property name="flushingModels">
    			<props>
    				<prop key="testFlushing">groups=pb_test</prop>
    			</props>
    		</property>
    	</bean>
    
    	<!-- 基于注解查找刷新缓存业务方法的AOP通知器 -->
    	<bean id="flushingAttributeSourceAdvisor"
    		class="org.springmodules.cache.interceptor.flush.FlushingAttributeSourceAdvisor">
    		<constructor-arg ref="flushingInterceptor" />
    	</bean>
    
    	<bean id="testCache" class="com.TestCache"/>
    
    </beans>
    

     
    2)命名空间配置

    <?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:oscache="http://www.springmodules.org/schema/oscache"
    	xsi:schemaLocation="
    			http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    			http://www.springmodules.org/schema/oscache http://www.springmodules.org/schema/cache/springmodules-oscache.xsd">
    
    <!-- 这里可以不需要配置这个
    	<bean id="autoproxy" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
     -->
    	
    	<oscache:config configLocation="classpath:oscache.properties" id="cacheProvider"/>
    	
    	<oscache:annotations providerId="cacheProvider">
    		<oscache:caching id="testCaching" groups="pb_test" cronExpression="0 1 * * *" refreshPeriod="86400"/>
    		<oscache:flushing id="testFlushing" groups="pb_test"/>
    	</oscache:annotations>
    	
    	<bean id="testCache" class="com.TestCache"/>
    	
    </beans>
    

    四.注解

      @Cacheable:声明一个方法的返回值应该被缓存

    例如:@Cacheable(modelId = "testCaching")

      @CacheFlush:声明一个方法是清空缓存的触发器

    例如:@CacheFlush(modelId = "testCaching")

    五.测试

      这是用使用一个带有main函数的类来进行测试,代码如下:

    /*
    * COPYRIGHT Beijing NetQin-Tech Co.,Ltd.                                   *
    ****************************************************************************
    * 源文件名: TestCache.java 														       
    * 功能: (描述文件功能)													   
    * 版本:	@version 1.0	                                                                   
    * 编制日期: 2010-2-24							    						   
    * 说明: (描述使用文件功能时的制约条件)                                       
    * 修改历史: (主要历史变动原因及说明)		
    * YYYY-MM-DD |    Author      |	 Change Description		      
    * 2010-2-24   |  hanqunfeng    |  Created 
    */
    package com;
    
    import net.sf.ehcache.CacheManager;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    import org.springmodules.cache.annotations.CacheFlush;
    import org.springmodules.cache.annotations.Cacheable;
    
    import com.opensymphony.oscache.general.GeneralCacheAdministrator;
    
    public class TestCache {
    
    	/**                                                          
    	 * 描述 : <描述函数实现的功能>. <br>
    	 *<p>                                                 
    	                                                                                                                                                                                                      
    	 * @param args                                                                                    			   
    	 */
    	static String context = null;
    	static ApplicationContext applicationContext;
    
    	static{
    		context = "applicationContext-ehcache.xml";//ehcache简单配置(命名空间)
    //		context = "applicationContext-ehcache_full.xml";//ehcache完整配置
    //		context = "applicationContext-oscache.xml";//oscache简单配置(命名空间)
    //		context = "applicationContext-oscache_full.xml";//oscache完整配置
    		
    		applicationContext = new ClassPathXmlApplicationContext(context);
    	}
    	public static void main(String[] args) {
    	    TestCache test = (TestCache)applicationContext.getBean("testCache");
    	    System.out.println(test.getName(0));
    	    System.out.println(test.getName(0));
    	    System.out.println(test.getName(0));
    	    test.flush();
    //	    test.OSFlushAll();
    //	    test.EHFlushAll();
    	    System.out.println(test.getName(0));
    	    System.out.println(test.getName(0));
    	    System.out.println(test.getName(0));
    	    
    
    	}
    	@Cacheable(modelId = "testCaching")
    	public String getName(int i){
    		System.out.println("Processing testCaching");
    		return "nihao:"+i;
    	}
    	
    	@CacheFlush(modelId = "testFlushing")
    	public void flush(){
    		System.out.println("Processing testFlushing");
    	}
    	
    	/**                                                          
    	* 描述 : <OSCache刷新全部缓存>. <br>
    	*<p>                                                 
    	     问题:flushAll() 后不会再缓存数据                                                                                                                                                                                                                                                                                    			   
    	*/
    	public void OSFlushAll(){
    		GeneralCacheAdministrator cacheAdmin = (GeneralCacheAdministrator)applicationContext.getBean("cacheManager");
    		cacheAdmin.flushAll();
    		System.out.println("Processing OSFlushingAll");
    	}
    	
    	/**                                                          
    	* 描述 : <清空指定组名称的缓存>. <br>
    	*<p>                                                 
    	                                                                                                                                                                                                      
    	* @param groupName                                                                                    			   
    	*/
    	public void OSFlushGroup(String groupName){
    		GeneralCacheAdministrator cacheAdmin = (GeneralCacheAdministrator)applicationContext.getBean("cacheManager");
    		cacheAdmin.flushGroup(groupName);//清除该组的缓存:pb_test
    		System.out.println("Processing OSFlushingGroup:"+groupName);
    	}
    	
    	/**                                                          
    	* 描述 : <EHCache刷新全部缓存>. <br>
    	*<p>                                                 
    	    success                                                                                                                                                                                                                                                                    			   
    	*/
    	public void EHFlushAll(){
    		CacheManager cacheAdmin = (CacheManager)applicationContext.getBean("cacheManager");
    		cacheAdmin.clearAll();	
    		System.out.println("Processing EHFlushingAll");
    	}
    	
    	/**                                                          
    	* 描述 : <清空指定名称的缓存>. <br>
    	*<p>                                                 
    	                                                                                                                                                                                                      
    	* @param cacheName                                                                                    			   
    	*/
    	public void EHFlushCache(String cacheName){
    		CacheManager cacheAdmin = (CacheManager)applicationContext.getBean("cacheManager");
    		cacheAdmin.getCache(cacheName).flush();//清除单个缓存:testCache	
    		System.out.println("Processing EHFlushingCacheName:"+cacheName);
    	}
    	
    
    }
    

     测试结果

    Processing testCaching
    nihao:0
    nihao:0
    nihao:0
    Processing testFlushing
    Processing testCaching
    nihao:0
    nihao:0
    nihao:0

    六.缓存配置文件

    ehcache.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true"
    	monitoring="autodetect">
    	<diskStore path="java.io.tmpdir"/>
        <defaultCache
                maxElementsInMemory="10000"
                eternal="false"
                timeToIdleSeconds="120"
                timeToLiveSeconds="120"
                overflowToDisk="true"
                maxElementsOnDisk="10000000"
                diskPersistent="false"
                diskExpiryThreadIntervalSeconds="120"
                memoryStoreEvictionPolicy="LRU"
                />
    	 <cache name="testCache"
               maxElementsInMemory="10000"
               maxElementsOnDisk="1000"
               eternal="false"
               overflowToDisk="true"
               diskSpoolBufferSizeMB="20"
               timeToIdleSeconds="300"
               timeToLiveSeconds="600"
               memoryStoreEvictionPolicy="LFU"
                />
    </ehcache>
    

     oscache.properties

      1. cache.capacity=5000 
  • 相关阅读:
    题解 P5320
    Codeforces 1500F
    三个 AGC D(AGC037D、AGC043D、AGC050D)
    Atcoder Regular Contst 084 D
    DG-基础知识点整理
    MySQL-数据恢复场景实验
    MySQL-查看Galera集群状态
    MySQL-运行日志切割
    MySQL-生产环境删除大表或大量binlog策略
    MySQL-基于(MySQL 5.7)NDB中启用共享权限表
  • 原文地址:https://www.cnblogs.com/wcyBlog/p/3945371.html
Copyright © 2011-2022 走看看