Spring AOP+EHCache简单缓存系统解决方案

需要使用Spring来实现一个Cache简单的解决方案,具体需求如下:使用任意一个现有开源Cache Framework,要求可以Cache系统中Service或则DAO层的get/find等方法返回结果,如果数据更新(使用Create/update/delete方法),则刷新cache中相应的内容。 MethodCacheInterceptor.java

Java代码 
package com.co.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;    
   
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.");    
    }    
   

上面的代码中可以看到,在方法public Object invoke(MethodInvocation invocation) 中,完成了搜索Cache/新建cache的功能。

Java代码 
Element element = cache.get(cacheKey);

这句代码的作用是获取cache中的element,如果cacheKey所对应的element不存在,将会返回一个null值

Java代码 
result = invocation.proceed(); 

这句代码的作用是获取所拦截方法的返回值,详细请查阅AOP相关文档。

随后,再建立一个拦截器MethodCacheAfterAdvice,作用是在用户进行create/update/delete操作时来刷新/remove相关cache内容,这个拦截器实现了AfterReturningAdvice接口,将会在所拦截的方法执行后执行在public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3)方法中所预定的操作

Java代码 
package com.co.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;    
   
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.");    
    }    
   
}

上面的代码很简单,实现了afterReturning方法实现自AfterReturningAdvice接口,方法中所定义的内容将会在目标方法执行后执行,在该方法中

Java代码 
String className = arg3.getClass().getName(); 


的作用是获取目标class的全名,如:com.co.cache.test.TestServiceImpl,然后循环cache的key list,remove cache中所有和该class相关的element。

随后,开始配置ehCache的属性,ehCache需要一个xml文件来设置ehCache相关的一些属性,如最大缓存数量、cache刷新的时间等等. 
ehcache.xml

Java代码 
<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>

 

转Spring+Hibernate+EHcache配置(二)的更多相关文章

  1. 【转】Spring+Hibernate+EHcache配置(一)

    大量数据流动是web应用性能问题常见的原因,而缓存被广泛的用于优化数据库应用.cache被设计为通过保存从数据库里load的数据来减少应用和数据库之间的数据流动.数据库访问只有当检索的数据不在cach ...

  2. 转Spring+Hibernate+EHcache配置(三)

    配置每一项的详细作用不再详细解释,有兴趣的请google下 ,这里需要注意一点defaultCache标签定义了一个默认的Cache,这个Cache是不能删除的,否则会抛出No default cac ...

  3. Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作

    详细的Spring MVC框架搭配在这个连接中: Maven 工程下 Spring MVC 站点配置 (一) Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作 这篇主 ...

  4. Spring+Hibernate整合配置 --- 比较完整的spring、hibernate 配置

    Spring+Hibernate整合配置 分类: J2EE2010-11-25 17:21 16667人阅读 评论(1) 收藏 举报 springhibernateclassactionservlet ...

  5. 笔记59 Spring+Hibernate整合(二)

    一.项目结构 二.创建表 数据库中只有一张表,stock,三个字段:stock_id.stock_code和stock_name. CREATE TABLE `stock` ( `STOCK_ID` ...

  6. Spring Security认证配置(二)

    学习本章之前,可以先了解下上篇Spring Security基本配置. 本篇想要达到这样几个目的: 1.访问调用者服务时,如果是html请求,则跳转到登录页,否则返回401状态码和错误信息 2.调用方 ...

  7. Hibernate+EhCache配置二级缓存

    步骤: 第一步:加入ehcache.jar 第二步: 在src目录下新建一个文件,名为:ehcache.xml 第三步:在hibernate配置文件的<session-factory>下配 ...

  8. SSH(Struts+spring+hibernate)配置

    1.spring和struts 1)web.xml 配置spring的ContextLoaderListener(监听器) 配置Struts的StrutsPrepareAndExecuteFilter ...

  9. Maven搭建struts2+spring+hibernate环境

    Maven搭建struts2+spring+hibernate环境(一) 本文简单的使用STS的自带的maven插件工具搭建ssh(struts2+spring+hibernate)开发环境,图文并茂 ...

随机推荐

  1. winform 渐变(非API)

    public FrmMain() { InitializeComponent(); //窗体显示特效 Opacity = 0.0; //窗体透明度为0 fadeTimer.Start(); //计时开 ...

  2. Unity3d发布错误:could not allocate memery:system out of memery!

    可能出现的原因: 1.项目太大了2.项目坏了3.资源坏了4.单个资源定点数超了e.   解决办法:删除了一些模型.是模型太大,面数.顶点数太多的原因.   Unity3d里查看模型的顶点数 展开fbx ...

  3. Android的ListView分页功能

    一.功能分析----ListView“加载更多”,功能如下图所示: 这个效果是当你上拉拖动页面时(注意有区别于下拉刷新),页面提示正在加载,2秒后显示留言更多内容:具体功能知道那我就来讲解下如何实现这 ...

  4. 有道单词本添加js实现自动阅读单词

    个人比较习惯使用有道,使用了一段时间,背单词的时候很不方便   而有道单词客户Duan没有自动阅读的功能,  本菜用强大的js实现了简单的自动下一个单词的功能, 方法:第一步打开有道路径下的" ...

  5. axure注册码

    ahjesus Axure RP 7.0注册码 用户名:axureuser 序列号:8wFfIX7a8hHq6yAy6T8zCz5R0NBKeVxo9IKu+kgKh79FL6IyPD6lK7G6+t ...

  6. 笔试面试题-小米Git

    题目描述: git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常 ...

  7. Z-Stack ZMain学习

    [注:本文源自博客园http://www.cnblogs.com/cherishui/,为尊重劳动者成果,如需转载请保留此行] 在TI已有的Z-Stack的工程下面,打开已有的demo文件,通过分析不 ...

  8. JDK中工具类的使用

    JDK中内置了很多常用的工具类,且多以“s”结尾,如:集合工具类Collections,数组工具类Arrays,对象工具类Objects,文件工具类Files,路径工具类Paths,数学工具类Math ...

  9. [CSS]三角形

    CSS盒子模型 当我们把padding和width,height全部设置为0,border设为一个较大的像素时 即:我们需要什么方向的三角形,只需把其余的三角形背景色设置为transparent:

  10. sublime 编辑完自动生成tmp的备份

    是安装phptool之后造成的,卸载即可 http://bbs.csdn.net/topics/390826865