利用Spring AOP 缓存方法结果集

我们都知道Hibernate可以用ehcache来作为Second Level Cache.主要是针对POJO的缓存,而且缓存的读取
在Hibernate中是写死.实际运用中感觉很不灵活.今天看到一篇介绍利用Spring Interceptor 来缓存指定
方法结果的例子,感觉很不错,充分体会到AOP的强大力量 :)
首先配置ehcache.xml
 <ehcache>

 

字串3

    <diskStorepath="java.io.tmpdir"/>
    <cachename="org.taha.cache.METHOD_CACHE"
        maxElementsInMemory="300"
        eternal="false"
        timeToIdleSeconds="500"
        timeToLiveSeconds="500"
        overflowToDisk="true"
        />
</ehcache>
 
接下在Spring配置文件中定义Ehcache组件
 
<beanid="cacheManager"class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
 <propertyname="configLocation">
    <value>classpath:ehcache.xml</value>
 </property>
</bean>
 
<beanid="methodCache"class="org.springframework.cache.ehcache.EhCacheFactoryBean">
 <propertyname="cacheManager">
    <reflocal="cacheManager"/>
 </property>
 <propertyname="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.javav1.02004-11-2814:57:00ZnjqExp$
 *@author<a href="mailto:znjq1980@etang.com">Znjq</a>
 */
publicclass MethodCacheInterceptor implements MethodInterceptor,
        InitializingBean {
    private Cache cache;
 
    /**
     *setscachenametobeused
     */
    publicvoid 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();
    }
 
    /**
     *createscachekey: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()
     */
    publicvoid afterPropertiesSet() throws Exception {
        // TODO Auto-generated method stub
 
    }
}
invoke方法中,首先根据key查询缓存(key=className + methodName + arguments)
,缓存中存在则返回,否之调用invocation.proceed()返回结果.
Spring配置文件中定义拦截器
<beanid="methodCacheInterceptor"class="org.taha.interceptor.MethodCacheInterceptor">
 <propertyname="cache">
    <reflocal="methodCache"/>
 </property>
</bean>
 
<beanid="methodCachePointCut"class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
 <propertyname="advice">
    <reflocal="methodCacheInterceptor"/>
 </property>
 <propertyname="patterns">
    <list>
      <value>.*methodOne</value>
      <value>.*methodTwo</value>
    </list>
 </property>
</bean>
 
<beanid="myBean"class="org.springframework.aop.framework.ProxyFactoryBean">
 <propertyname="target">
   <beanclass="org.taha.beans.MyBean"/>
 </property>
 <propertyname="interceptorNames">
    <list>
      <value>methodCachePointCut</value>
    </list>
 </property>
</bean>
这里org.springframework.aop.support.RegexpMethodPointcutAdvisor是一个正规表达式切入点,
使用Perl 5的正规表达式的语法, 基Jakarta ORO。(有空写个文档,自己研究一下).
 <propertyname="target">
   <beanclass="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方法进行调用,都会首先从缓存查找,
其次才会查询数据库. 这样我就不需要在xx.hbm.xml来指定讨厌的cache.也不需要在开发阶段来关心缓存.
一切AOP搞定.. ^_^
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值