使用spring3.0的cache方案解决缓存问题

Spring缓存实践
本文介绍如何使用Spring缓存模块实现高效的数据缓存管理。通过自定义缓存Key生成器和配置缓存通知,实现对特定服务方法的缓存。文章详细讲解了缓存的实现原理及步骤,并提供了具体配置实例。

缓存:

----------------------------------------------------------------------------------------

实现原理:
      通过spring的缓存模块,进行spring缓存
配置缓存管理器及缓存通知,对某个service进行代理,然后配置其中需要缓存数据的方法一级需要清理缓存数据的方法

定义一个缓存key生成器,会根据当前被缓存的方法的参数生成一个key,然后把key缓存起来,并把查询的结果也缓存起来,


对应关系是这样:
类.方法--n-->key--1--查询结果
      每个方法根据参数不同会生成n个不同的key,每个key查询的结果只有一个
当每次来请求这个方法时,把当前请求的参数,生成一个key,然后上这个方法的缓存中查询有没有相同的key(等同于查询参数一样的情况),
如果有则不查数据库了,直接把缓存的结果拿出来,如果没有则上数据库查询结果,然后把key和结构缓存起来
,当指定的需要清理缓存的结果执行时,就会清空缓存中的数据,因为指定的方法一般为谢操作,会改变数据库中的数据,这时缓存的数据就是过期数据了。




步骤:
--------------------------------------------------------
1.抽取spring-cache-3.1.xsd文件进行注册.
org.springframework.context-3.1.0.RELEASE.jar/org.springframework.cache:缓存抽象包
2.配置beans.xml文件中的缓存通知和切入点

3.自定义key生成器.
------------------------------------------------------






下面给出小例子:


1,编写生成缓存key的类

--------------------------------------------

package cn.hl.test.cache;

import java.lang.reflect.Method;
import org.springframework.cache.interceptor.KeyGenerator;
/**
 * 自定义缓存可以生成器
 */
public class SurveyKeyGenerator implements KeyGenerator {

	public Object generate(Object arg0, Method arg1, Object... arg2) {
		String targHashCode = arg0.getClass().getSimpleName() + "["+arg0.hashCode()+"]" ;
		String mname = arg1.getName();
		String key = null ;
		//有参数的情况
		if(arg2 != null && arg2.length > 0){
			StringBuffer buffer = new StringBuffer();
			for(Object p : arg2){
				buffer.append(p.toString() + ",");
			}
			//调用md5方法对参数toString的信息加密,防治参数过长
			key = targHashCode + "." + mname + "("+DataUtil.md5(buffer.toString())+")"; 
			System.out.println(key);
			return key ;
		}
		//没有参数的情况
		key = targHashCode + "." + mname +"()";
		System.out.println(key);
		return key;
	}
}


2,spring文件配置(缓存通知和切入点)
--------------------------------------------

<?xml version="1.0"?>
<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:tx="http://www.springframework.org/schema/tx" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xmlns:cache="http://www.springframework.org/schema/cache" 
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.0.xsd 
http://www.springframework.org/schema/tx 
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd 
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache-3.1.xsd ">
	
	<!-- 缓存管理器工厂(创建各种缓存管理器) -->
	<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<!-- ehcache配置文件,配置的是缓存的过期策略 -->
		<property name="configLocation" value="classpath:ehcache.xml" />
	</bean>
	
	<!-- ehcache缓存管理器 -->
	<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
		<property name="cacheManager" ref="ehcache" />
	</bean>
	
	<!-- 缓存key生成器 -->
	<bean id="surveyKeyGenerator" class="cn.hl.test.cache.SurveyKeyGenerator" />
	
	<!-- 定义缓存通知 -->
	<cache:advice id="cacheAdivce" cache-manager="cacheManager" key-generator="surveyKeyGenerator">
		<!-- 缓存区 cache="surveyCache"   与ehcache.xml文件中的缓存区名保持一致-->
		<cache:caching cache="surveyCache">
			<!-- 缓存数据 -->
			<cache:cacheable method="get*"/>
			<cache:cacheable method="load*"/>
			<cache:cacheable method="find*"/>
			<cache:cacheable method="is*"/>
			
			<!-- 移除缓存数据,all-entries所有条目-->			
			<cache:cache-evict method="save*" all-entries="true"/>
			<cache:cache-evict method="update*" all-entries="true"/>
			<cache:cache-evict method="delete*" all-entries="true"/>
			<cache:cache-evict method="batch*" all-entries="true"/>
		</cache:caching>
	</cache:advice>
	
	<!-- aop配置 -->
	<aop:config>
		<!-- 缓存通知 配置切入点,具体缓存那个service的方法  排除那些方法 -->
		<aop:advisor advice-ref="cacheAdivce" 
			pointcut="execution(* cn.hl.test.service.SurveyService.*(..)) and !execution(* cn.hl.test.service.SurveyService.saveAnswers(..))" 
			order="0"/>
	</aop:config>
</beans>


3,ehcache.xml文件配置(缓存过期策略)
--------------------------------------------

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <diskStore path="java.io.tmpdir"/>
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />
	<!-- 缓存区的名称  name="surveyCache" -->
    <cache name="surveyCache"
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            maxElementsOnDisk="10000000"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
            />
</ehcache>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值