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. C# 4 dynamic 动态对象 动态类型转换

    public class User { //使用省缺参数,一般不需要再为多态做各种静态重载了 public User( string name = "anonym", string ...

  2. 解决MS Office下载网站数据失败的问题

    最近遇到在MS Excel中建立的Web Query在创建完成后过了一段时间(或关闭文件后再次打开文件并刷新数据)出现无法刷新的问题,点击刷新时报错如下: 无法下载您要求的信息. 这是一个很不友好的报 ...

  3. HDOJ2008数值统计

    数值统计 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  4. Android之单选框

    MainActivity继承Activity使用OnCheckedChangeListener接口: package com.cdp.checkbox; import android.app.Acti ...

  5. 如何设置Win7系统中的上帝模式GodMode(转载)

    如何设置Win7系统中的上帝模式GodMode(转载) NT6系统中隐藏了一个秘密的“GodMode”,字面上译为“上帝模式”.God Mode其实就是一个简单的文件夹窗口,但包含了几乎所有系统的设置 ...

  6. 【整理】c# 调用windows API(user32.dll)

    User32.dll提供了很多可供调用的接口,大致如下(转自http://blog.csdn.net/zhang399401/article/details/6978803) using System ...

  7. md5值计算

    1.md5(Message Digest 5th/消息概要加密算法 第5版) REFER: MD5 On wikipedia 2.应用范围 ① 验证下载文件的完整性 ② 3.关于MD5的几个问题 ①只 ...

  8. 学习C++ Primer 的个人理解(一)

    <C++ Primer>这本书可以说是公认的学习C++最好的书,但我觉得不是特别适合作为教材,书中内容的顺序让人有些蛋疼.我个人认为初学此书是不能跳着看的.如果急于上手的话,我更推荐< ...

  9. main与进程 线程

    你起一个CS游戏,这上CS游戏在操作系统中就是一个进程. 但是这个游戏一边在打枪,一边人在走动,一边还有音乐 ,打枪 , 走动 , 音乐 等都是一些线程. 线程不是由进程决定了. 也就是说:你在操作系 ...

  10. IDEA 2016.2.2激活地址(2016-08-22)

    http://idea.imsxm.com/ 2016/10/13  http://idea.iteblog.com/key.php