缓存:
----------------------------------------------------------------------------------------
实现原理:通过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>