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. [转]IOS, xib和storyboard的混用

    1. 从xib的viewcontroll中启动storyboard 或者 从一个storyboard切换到另一个storyboard: [objc]– (IBAction)openStoryboard ...

  2. Oracle 简介 三层结构

    引言: 主流数据库:sql server, oracle, my sql,IBM公司的DB2 ,oracle占有量很大 dbms(database management system)数据库管理系统 ...

  3. Cocos移植到Android-使用Eclipse交叉编译打包

    如果对命令行望而生畏,我们可以借助于安装有ADT插件的Eclipse工具实现交叉编译.使用Eclipse进行交叉编译,首先需要将要编译的工程导入到Eclipse的Workspace中,Workspac ...

  4. OpenGL5-纹理贴图

    代码下载 #include "CELLWinApp.hpp"#include <gl/GLU.h>#include <assert.h>#include & ...

  5. (转)关于redis、memcache、mongoDB 的对比

    从以下几个维度,对redis.memcache.mongoDB 做了对比,欢迎拍砖 1.性能 都比较高,性能对我们来说应该都不是瓶颈 总体来讲,TPS方面redis和memcache差不多,要大于mo ...

  6. 总是你 2008-3 (献给L之一)

    文/安然 总是你 是梦里的那份最温柔 轻轻碰触 不再敢轻易提及 总是你 是不经意的那份最感动 点点鲜活 从来就没有淡去 时间远走 我轻轻的收起 那段记忆 不再开启 但是 偶尔 偶尔 总是 总是在不经意 ...

  7. spring 中的 RowMapper

    spring 中的 RowMapper sping中的RowMapper可以将数据中的每一行数据封装成用户定义的类.    我们在数据库查询中,如果返回的类型是用户自定义的类型(其实我们在数据库查询中 ...

  8. springMVC整合memcached

    非原创,文章转自:http://www.cnblogs.com/xiaoqingxin/p/4132391.html 文章我就不全copy了,摘抄下我关注的部分,想看原文的请移步上面文章链接 appl ...

  9. DTCMS更改图片相册上传图片类型,手机上传图片相册

    /admin/js/uploader.js 中 filetypes: "jpg,jpge,png,gif", //文件类型 改为 filetypes: "jpg,jpeg ...

  10. 5步解决移动设备上的300ms点击延迟

    译者:jmouse 大多数基于触摸的浏览器设备,在点击时都会有个 300ms 的事件触发等待时间,做过 web app 开发的同学应该都遇到过这个情况,通过下面的5步可以轻松搞定这个延迟. 1.不要太 ...