分享

利用Spring aop 自带的ehcache来缓存对象。

 Joshua 2005-12-30
1.采用ehcache来缓存得到的对象结合Spring aop实现通过MethodCacheInterceptor类拦截器来实现:
java代码: 

/*
* 创建日期 2005-3-15
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/

package com.cnsi.softer.interceptor.MethodCacheInterceptor;



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;


/**
* @author Administrator
*
* TODO 要更改此生成的类型注释的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/

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();
                // TODO 自动生成构造函数存根
        }

          /**
           * 主方法
           * 如果某方法可被缓存就缓存其结果
           * 方法结果必须是可序列化的(serializable)
           */

          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("在缓存中查找方法返回的对象!");
            String cacheKey = getCacheKey(targetName, methodName, arguments);
            Element element = cache.get(cacheKey);
            if (element == null) {
                 logger.debug("正在拦截方法!");
                 result = invocation.proceed();

                 logger.debug("正在缓存对象!");
                 element = new Element(cacheKey, (Serializable) result);
                 cache.put(element);
            }
            return element.getValue();
          }

          /**
           *创建一个缓存对象的标识: targetName.methodName.argument0.argument1...
           */

          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();
          }



        /* £ǚÇ Javadoc)
        * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
        */

        public void afterPropertiesSet() throws Exception {
                Assert.notNull(cache, "需要一个缓存. 使用setCache(Cache)分配一个.");

        }

}


当程序中的如create方法,update方法,delete方法修改了内存中的对象值时,通过如下的通知来除去此对象:
java代码: 

/*
* 创建日期 2005-3-15
*
* TODO 要更改此生成的文件的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/

package com.cnsi.softer.interceptor.MethodCacheInterceptor;

import java.lang.reflect.Method;

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;

/**
* @author Administrator
*
* TODO 要更改此生成的类型注释的模板,请转至
* 窗口 - 首选项 - Java - 代码样式 - 代码模板
*/

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();
        }

        /* (非 Javadoc)
        * @see org.springframework.aop.AfterReturningAdvice#afterReturning(java.lang.Object, java.lang.reflect.Method, java.lang.Object[], java.lang.Object)
        */

        public void afterReturning(Object arg0, Method arg1, Object[] arg2,
                        Object arg3) throws Throwable {
                    StringBuffer buffer = new StringBuffer();
                    buffer.append(arg3.getClass().getName()).append(".").append(arg1.getName());
                    if (arg2 != null&&arg2.length != 0){
                              for (int i=0; i<arg2.length; i++) {
                                buffer.append(".")
                                  .append(arg2[i]);
                              }
                           
                    }
                    cache.remove(buffer);
        }

        /* (非 Javadoc)
        * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
        */

        public void afterPropertiesSet() throws Exception {
                Assert.notNull(cache, "需要一个缓存. 使用setCache(Cache)分配一个.");
    }

}


2.我的配置文件如下:
由于发现直接把文件贴出来,定义的bean标签都不见了,所以还是上传一个文件附件吧,大家打开文件看看

假若可以这样配置是不是在serviceCache和serviceCacheAdvice对象中就会存在多个target对象,对内存的要求就会增大呢?
3.这样配置后,就可以了对巴,用不用在其他地方注入newsServiceCache,和newsServiceCacheAdvice。是自动执行的对巴

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多