利用Spring aop 自带的ehcache来缓存对象

本文介绍了一种利用EHCache结合Spring AOP实现方法级缓存的技术方案。通过自定义拦截器MethodCacheInterceptor和通知MethodCacheAfterAdvice,在Spring环境中实现了对查询方法结果的缓存及对修改方法后的缓存更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.采用ehcache来缓存得到的对象结合Spring aop实现通过MethodCacheInterceptor类拦截器来实现:

代码 
/*  
 * 创建日期 2005-3-15  
 *  
 * TODO 要更改此生成的文件的模板,请转至  
 * 窗口 - 首选项 - Java - 代码样式 - 代码模板  
 
*/
  
package com.cnsi.softer.interceptor.MethodCacheInterceptor;   
  
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.apache.commons.logging.Log;   
import org.apache.commons.logging.LogFactory;   
import org.springframework.beans.factory.InitializingBean;   
import org.springframework.util.Assert;   
  
/**  
 * 
@author Administrator  
 *  
 * TODO 要更改此生成的类型注释的模板,请转至  
 * 窗口 - 首选项 - Java - 代码样式 - 代码模板  
 
*/
  
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();   
        
// TODO 自动生成构造函数存根   
    }
   
  
      
/**  
       * 主方法  
       * 如果某方法可被缓存就缓存其结果  
       * 方法结果必须是可序列化的(serializable)  
       
*/
  
      
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.debug(
"在缓存中查找方法返回的对象!");   
        String cacheKey 
= getCacheKey(targetName, methodName, arguments);   
        Element element 
= cache.get(cacheKey);   
        
if (element == null{   
             logger.debug(
"正在拦截方法!");   
             result 
= invocation.proceed();   
  
             logger.debug(
"正在缓存对象!");   
             element 
= new Element(cacheKey, (Serializable) result);   
             cache.put(element);   
        }
   
        
return element.getValue();   
      }
   
  
      
/**  
       *创建一个缓存对象的标识: 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();   
      }
   
  
    
/* (非 Javadoc)  
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()  
     
*/
  
    
public void afterPropertiesSet() throws Exception {   
        Assert.notNull(cache, 
"需要一个缓存. 使用setCache(Cache)分配一个.");   
  
    }
   
  
}
当程序中的如create方法,update方法,delete方法修改了内存中的对象值时,通过如下的通知来除去此对象:
代码
/*  
 * 创建日期 2005-3-15  
 *  
 * TODO 要更改此生成的文件的模板,请转至  
 * 窗口 - 首选项 - Java - 代码样式 - 代码模板  
 
*/
  
package com.cnsi.softer.interceptor.MethodCacheInterceptor;   
  
import java.lang.reflect.Method;   
  
import net.sf.ehcache.Cache;   
  
import org.apache.commons.logging.Log;   
import org.apache.commons.logging.LogFactory;   
import org.springframework.aop.AfterReturningAdvice;   
import org.springframework.beans.factory.InitializingBean;   
import org.springframework.util.Assert;   
  
/**  
 * 
@author Administrator  
 *  
 * TODO 要更改此生成的类型注释的模板,请转至  
 * 窗口 - 首选项 - Java - 代码样式 - 代码模板  
 
*/
  
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();   
    }
   
  
    
/* (非 Javadoc)  
     * @see org.springframework.aop.AfterReturningAdvice#afterReturning(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], java.lang.Object)  
     
*/
  
    
public void afterReturning(Object arg0, Method arg1, Object[] arg2,   
            Object arg3) 
throws Throwable {   
            StringBuffer buffer 
= new StringBuffer();   
            buffer.append(arg3.getClass().getName()).append(
".").append(arg1.getName());   
            
if (arg2 != null&&arg2.length != 0){   
                  
for (int i=0; i<arg2.length; i++{   
                    buffer.append(
".")   
                      .append(arg2[i]);   
                  }
   
                   
            }
   
            cache.remove(buffer);   
    }
   
  
    
/* (非 Javadoc)  
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()  
     
*/
  
    
public void afterPropertiesSet() throws Exception {   
        Assert.notNull(cache, 
"需要一个缓存. 使用setCache(Cache)分配一个.");   
    }
   
  
}
  

2.配置文件如下:

<!--使用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>
<bean id="methodCacheInterceptor" class="com.cnsi.softer.interceptor.MethodCacheInterceptor.MethodCacheInterceptor">
  
<property name="cache">
    
<ref local="methodCache" />
  
</property>
</bean>
<bean id="methodCacheAfterAdvice" class="com.cnsi.softer.interceptor.MethodCacheInterceptor.MethodCacheAfterAdvice">
  
<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>.*find.*</value>
      
<value>.*get.*</value>
    
</list>
  
</property>
</bean>
<bean id="methodCacheAdvicePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
  
<property name="advice">
    
<ref local="methodCacheAfterAdvice"/>
  
</property>
  
<property name="patterns">
    
<list>
      
<value>.*create.*</value>
      
<value>.*save.*</value>
      
<value>.*delete.*</value>
    
</list>
  
</property>
</bean>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值