利用Spring AOP 緩存方法結果集
我們都知道Hibernate可以用ehcache來作為Second Level Cache.主要是針對POJO的緩存,而且緩存的讀取
在Hibernate中是寫死.實際運用中感覺很不靈活.今天看到一篇介紹利用Spring Interceptor 來緩存指定
方法結果的例子,感覺很不錯,充分體會到AOP的強大力量 :)
首先配置ehcache.xml
<ehcache>
<diskStore path="java.io.tmpdir"/> <cache name="org.taha.cache.METHOD_CACHE" 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實現(xiàn)了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:znjq1980@etang.com">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
} } |
invoke方法中,首先根據(jù)key查詢緩存(key=className + methodName + arguments)
,緩存中存在則返回,否之調(diào)用invocation.proceed()返回結果.
在Spring配置文件中定義攔截器
<bean id="methodCacheInterceptor" class="org.taha.interceptor.MethodCacheInterceptor"> <property name="cache"> <ref local="methodCache" /> </property> </bean>
<bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice"> <ref local="methodCacheInterceptor"/> </property> <property name="patterns"> <list> <value>.*methodOne</value> <value>.*methodTwo</value> </list> </property> </bean>
<bean id="myBean" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <bean class="org.taha.beans.MyBean"/> </property> <property name="interceptorNames"> <list> <value>methodCachePointCut</value> </list> </property> </bean> |
這里org.springframework.aop.support.RegexpMethodPointcutAdvisor是一個正規(guī)表達式切入點,
使用Perl 5的正規(guī)表達式的語法, 基Jakarta ORO。(有空寫個文檔,自己研究一下).
<property name="target"> <bean class="org.taha.beans.MyBean"/> </property> |
org.taha.beans.MyBean是我們需要做緩存處理的類.
methodCachePointCut中
<value>.*methodOne</value> <value>.*methodTwo</value> |
則是指定的模式匹配方法,對應于org.taha.beans.MyBean中的方法. 這里指定了2個方法需要做緩存處理.
呵呵,就是這么簡單.這樣每次對org.taha.beans.MyBean的methodOne方法進行調(diào)用,都會首先從緩存查找,
其次才會查詢數(shù)據(jù)庫. 這樣我就不需要在xx.hbm.xml來指定討厭的cache了.也不需要在開發(fā)階段來關心緩存.
一切AOP搞定.. ^_^
posted on 2005-04-11 15:17 輕松 閱讀(4243) 評論(3) 編輯 收藏 所屬分類: JAVA轉貼