• 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技术实现对拦截方法名的缓存处理

  • 相关阅读:
    使用MAVEN打JAR,直接使用
    回溯法最优装载问题(java)
    js-object引用示例
    网页自适应布局方案
    ajax的工作原理
    通过SublimeCodeIntel设置JavaScript自动补全
    sublime的Package Control的安装及使用
    Opencv 简单视频播放器
    OpenCV_复制一个或多个ROI图像区域
    OpenCV 2.4.8 or OpenCV 2.4.9组件结构全解析
  • 原文地址:https://www.cnblogs.com/fangj/p/SSH2_ehcahe.html
Copyright © 2020-2023  润新知