我们都知道Hibernate可以用ehcache来作为Second Level Cache.主要是针对POJO的缓存,而且缓存的读取
在Hibernate中是写死.实际运用中感觉很不灵活.今天看到一篇介绍利用Spring Interceptor 来缓存指定
方法结果的例子,感觉很不错,充分体会到AOP的强大力量 :)
首先配置ehcache.xml
<ehcache>
<defaultCache name="default" maxElementsInMemory="300" eternal="false" timeToIdleSeconds="500" timeToLiveSeconds="500" overflowToDisk="true" />
maxElementsInMemory="300" eternal="false" timeToIdleSeconds="500" timeToLiveSeconds="500" overflowToDisk="true" /> </ehcache> |
接下在Spring配置文件中定义Ehcache组件
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation"> <value>classpath:ehcache.xml</value> </property> </bean>
<bean id="methodCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager"> <ref local="cacheManager"/> </property> <property name="cacheName"> <value>org.taha.cache.METHOD_CACHE</value> </property> </bean> |
建立我们自己的方法拦截器MethodCacheInterceptor.
MethodCacheInterceptor实现了org.aopalliance.intercept.MethodInterceptor接口.
import java.io.Serializable;
import net.sf.ehcache.Cache; import net.sf.ehcache.Element;
import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.beans.factory.InitializingBean;
/** * 拦截器,用于缓存方法返回结果. * * @version $Id: MethodCacheInterceptor.java v 1.0 2004-11-28 14:57:00 Znjq Exp $ * @author <a href="mailto:[email protected]">Znjq </a> */ public class MethodCacheInterceptor implements MethodInterceptor, InitializingBean { private Cache cache;
/** * sets cache name to be used */ public void setCache(Cache cache) { this.cache = cache; }
/* * (non-Javadoc) * * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation) */ public Object invoke(MethodInvocation invocation) throws Throwable { String targetName = invocation.getThis().getClass().getName(); String methodName = invocation.getMethod().getName(); Object[] arguments = invocation.getArguments(); Object result;
String cacheKey = getCacheKey(targetName, methodName, arguments); Element element = cache.get(cacheKey); if (element == null) { //call target/sub-interceptor result = invocation.proceed();
//cache method result element = new Element(cacheKey, (Serializable) result); cache.put(element); } return element.getValue(); }
/** * creates cache key: targetName.methodName.argument0.argument1... */ 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(); }
/* * (non-Javadoc) * * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet() */ public void afterPropertiesSet() throws Exception { // TODO Auto-generated method stub
} } |