SSH2+ehcache实现代码

一、核心代码

package com.XX.cache.ehcache; import java.lang.reflect.Method; import java.util.List; 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; /** * * 使用spring的ehcahe * 作用是在用户进行create/update/delete操作时来刷新/remove相关cache内容,这个拦截器实现了AfterReturningAdvice接口,将会在所拦截的方法执行后执行在public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3)方法中所预定的操作 * @author fangj * 2013-08-14 * */ 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.debug("remove cache " + cacheKey); } } } public void afterPropertiesSet() throws Exception { Assert.notNull(cache, "Need a cache. Please use setCache(Cache) create it."); } }
package com.XX.cache.ehcache;

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;  
/**
 * 创建一个实现了MethodInterceptor接口的拦截器,用来拦截Service/DAO的方法调用,拦截到方法后,搜索该方法的结果在cache中是否存在,如果存在,返回cache中的缓存结果,如果不存在,返回查询数据库的结果,并将结果缓存到cache中
 * @author fangj
 * 2013-08-13
 */
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.debug("Find object from cache is " + cache.getName());  
          
        String cacheKey = getCacheKey(targetName, methodName, arguments);  
        Element element = cache.get(cacheKey);  
  
        if (element == null) {  
            logger.debug("Hold up method , Get method result and create cache........!");  
            result = invocation.proceed();  
            element = new Element(cacheKey, (Serializable) result);  
            cache.put(element);  
        }  
        return element.getValue();  
    }  
  
    /** 
     * 获得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, "Need a cache. Please use setCache(Cache) create it.");  
    }  
  
}  

 二、ehcahe配置文件

1、src目录下增加cacheContext.xml配置文件,内容如下

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
	<!-- 引用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.XX.cache.ehcache.MethodCacheInterceptor">
	  <property name="cache">
		<ref local="ehCache" />
	  </property>
	</bean>
	<!-- flush cache拦截器 -->
	<bean id="methodCacheAfterAdvice" class="com.XX.cache.ehcache.MethodCacheAfterAdvice">
	  <property name="cache">
		<ref local="ehCache" />
	  </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>
			<value>.*list.*</value>
			<value>.*List.*</value>
		</list>
	  </property>
	</bean>
	<!-- 触发更新缓存数据的方法-->
	<bean id="methodCachePointCutAdvice" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
	  <property name="advice">
		<ref local="methodCacheAfterAdvice"/>
	  </property>
	  <property name="patterns">
		<list>
		  <value>.*create.*</value>
		  <value>.*update.*</value>
		  <value>.*delete.*</value>
		  <value>.*edit.*</value>
		</list>
	  </property>
	</bean>
</beans>

 2、src目录下增加ehcache.xml配置文件

<ehcache>
	<diskStore path="c://myapp//cache"/>
	<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>

三、以上ehcahe的配置已基本完成,下一步是如果把这些配置在我们Struts2+spring2.5+hibernate3项目上整合上去

其实只需要修改spring的配置文件即可

    <import resource="classpath:cacheContext.xml"/>
<!-- 系统启动表 --> <bean id="systemsetupDao" parent="hibernateTransactionProxy" > <property name="target"> <bean class="com.XX.rent.rentsysteup.dao.RentSyentemSetupDaoImp" parent="genericHibernateDao"> <property name="hibernateTemplate"> <ref bean="hibernateTemplate" /> </property> </bean> </property> </bean> <bean id="systemsetupServiceTarget" class="com.XX.rent.rentsysteup.service.RentSyentemSetupServiceImpl"> <property name="syssetupdao"> <ref local="systemsetupDao" /> </property> </bean> <!-- 使用chcahe配置 --> <bean id="systemsetupService" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target"> <ref local="systemsetupServiceTarget"/> </property> <property name="interceptorNames"> <list> <value>methodCachePointCut</value> <value>methodCachePointCutAdvice</value> </list> </property> </bean>

 完成试用,其他的struts2,hibernate3的配置文件都不需要修改,全部由spring的AOP技术实现对拦截方法名的缓存处理

posted @ 2013-08-13 17:54  方坚.cn  阅读(1942)  评论(0编辑  收藏  举报