您的位置:首页 > 编程语言 > Java开发

spring aop的案例(二)缓存配置

2015-10-20 10:39 405 查看
缓存,为什么使用缓存?

重复的查询操作会让数据库做一些无用工作,缓存的引入让数据库减少了IO操作,减少了服务器的压力。ehcache是Java里最常用的一个缓存框架,它分为页面缓存和业务缓存,我们这里只说业务缓存。

首先新建一个ehcache.xml

<ehcache>
<!-- <diskStore path="F://ehcache//dir"/>-->
<diskStore path="java.io.tmpdir"/>
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
<cache name="DEFAULT_CACHE"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300000"
timeToLiveSeconds="600000"
overflowToDisk="true"
/>
</ehcache>


ehcache.xml中的diskStore 配置有本地缓存和IO缓存,java.io.tmpdir为IO缓存,需要消耗一定的服务器性能。

cache操作,新增缓存和删缓存

public class MethodCacheInterceptor implements MethodInterceptor, InitializingBean
{
private static final Log logger = LogFactory.getLog(MethodCacheInterceptor.class);

private Cache cache;

public void setCache(Cache cache) {
this.cache = cache;
}

public MethodCacheInterceptor() {
super();
}

/**
* 拦截Service/DAO的方法,并查找该结果是否存在,如果存在就返回cache中的值,
* 否则,返回数据库查询结果,并将查询结果放入cache
*/
public Object invoke(MethodInvocation invocation) throws Throwable {
String targetName = invocation.getThis().getClass().getName();
String methodName = invocation.getMethod().getName();
Object[] arguments = invocation.getArguments();
Object result;

logger.info("发现对象缓存来自 " + cache.getName());

String cacheKey = getCacheKey(targetName, methodName, arguments);
Element element = cache.get(cacheKey);

if (element == null) {
logger.info("保持方法,得到的结果和方法创建缓存........!");
result = invocation.proceed();
element = new Element(cacheKey, (Serializable) result);
cache.put(element);
}
return element.getObjectValue();
}

/**
* 获得cache key的方法,cache key是Cache中一个Element的唯一标识
* cache key包括 包名+类名+方法名,如com.co.cache.service.UserServiceImpl.getAllUser
*/
private String getCacheKey(String targetName, String methodName, Object[] arguments) {
StringBuffer sb = new StringBuffer();
sb.append(targetName).append(".").append(methodName);
if ((arguments != null) && (arguments.length != 0)) {
for (int i = 0; i < arguments.length; i++) {
sb.append(".").append(arguments[i]);
}
}
return sb.toString();
}

/**
* implement InitializingBean,检查cache是否为空
*/
public void afterPropertiesSet() throws Exception {
Assert.notNull(cache, "需要一个高速缓存。请使用setCache(Cache)创建它。");
}

}


public class MethodCacheAfterAdvice implements AfterReturningAdvice, InitializingBean
{
private static final Log logger = LogFactory.getLog(MethodCacheAfterAdvice.class);

private Cache cache;

public void setCache(Cache cache) {
this.cache = cache;
}

public MethodCacheAfterAdvice() {
super();
}

public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
String className = arg3.getClass().getName();
List<?> list = cache.getKeys();
//获取到该类中所有的缓存方法 清除之
for(int i = 0;i<list.size();i++){
String cacheKey = String.valueOf(list.get(i));
if(cacheKey.startsWith(className)){
cache.remove(cacheKey);
logger.info("删除缓存 " + cacheKey);
}
}
}

public void afterPropertiesSet() throws Exception {
Assert.notNull(cache, "需要一个缓存. 请使用setCache(Cache) 创建它.");
}

}


spring-cache.xml配置

<!-- 引用ehCache的配置 -->
<bean id="defaultCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation">
<value>classpath: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.iitdev.cache.MethodCacheInterceptor">
<property name="cache">
<ref local="ehCache" />
</property>
</bean>
<!-- flush cache拦截器 -->
<bean id="methodCacheAfterAdvice" class="com.iitdev.cache.MethodCacheAfterAdvice">
<property name="cache">
<ref local="ehCache" />
</property>
</bean>

<bean id="methodCachePointCut" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice">
<ref local="methodCacheInterceptor"/>
</property>
<property name="mappedNames">
<list>
<value>find*</value>
<value>get*</value>
<value>search*</value>
<value>select*</value>
</list>
</property>
</bean>
<bean id="methodCachePointCutAdvice" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice">
<ref local="methodCacheAfterAdvice"/>
</property>
<property name="mappedNames">
<list>
<value>modify*</value>
<value>delete*</value>
<value>insert*</value>
<value>save*</value>
</list>
</property>
</bean>


使用自动装配bean设置缓存拦截器

<!-- 自动装配事务到bean -->
<bean id="autoTrx"          class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*BS</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>trxInterceptor</value>
<value>methodCachePointCutAdvice</value>
<value>methodCachePointCut</value>
</list>
</property>
</bean>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: