Spring aop 缓存控制

公司要做的在线统计,由于数据10分钟才更新一次,因此打算让查询结果在内存中缓存1分钟,我这里拦截了service层的

getOnlineByDate方法

 

拦截的Interceptor代码如下,参考了http://www.blogjava.net/relax/archive/2005/04/11/3141.html

package com.xxx.stat.online.aop;

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.springframework.beans.factory.InitializingBean;

public class MethodCacheInterceptor implements MethodInterceptor,
        InitializingBean {

    private Cache cache;
    /**
     * sets cache name to be used
     */

    public void setCache(Cache cache) {
        this.cache = cache;
    }    
    
    @Override
    public void afterPropertiesSet() throws Exception {

    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        String targetName = invocation.getThis().getClass().getName();
        String methodName = invocation.getMethod().getName();
        Object[] arguments = invocation.getArguments();
        Object result;

        String cacheKey = getCacheKey(targetName, methodName, arguments);
        System.out.println("cacheKey is "+cacheKey);
        Element element = cache.get(cacheKey);
        if (element == null) {
            System.out.println("read result from db");
            //call target/sub-interceptor
            result = invocation.proceed();
            //cache method result
            element = new Element(cacheKey, (Serializable) result);
            cache.put(element);
        }else{
            System.out.println("read result from cache");
        }
        System.out.println("read result from cache");
        return element.getValue();
    }

    /**
     * creates cache key: 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();

    }    
}

 

spring的配置如下

	<!-- cache configuration starts here -->
	<bean id="cacheManager"
		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
		<property name="configLocation">
			<value>classpath:ehcache.xml</value>
		</property>
	</bean>

	<bean id="methodCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
		<property name="cacheManager">
			<ref local="cacheManager" />
		</property>
		<property name="cacheName">
			<value>com.xxx.stat.serverOnline.namedQuery.query1</value>
		</property>
	</bean>

	<bean id="methodCacheInterceptor" class="com.xxx.stat.online.aop.MethodCacheInterceptor">
		<property name="cache">
			<ref local="methodCache" />
		</property>
	</bean>

	<bean id="methodCachePointCut"
		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice">
			<ref local="methodCacheInterceptor" />
		</property>
		<property name="patterns">
			<list>
				<value>.*getOnlineByDate.*</value>
			</list>
		</property>
	</bean>



	<bean id="myBean" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
		<property name="beanNames"><value>serverOnlineManager</value></property>
		<property name="interceptorNames">
			<list>
				<value>methodCachePointCut</value>
			</list>
		</property>
	</bean>

 注意这里的myBean的class是org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator

 网上很多文章讲要这样配置(用org.springframework.aop.framework.ProxyFactoryBean ):

<bean id="myBean" class="org.springframework.aop.framework.ProxyFactoryBean">
  <property name="target">
   <ref local="serverOnlineManager"/>
  </property>
  <property name="interceptorNames">
    <list>
      <value>methodCachePointCut</value>
    </list>
  </property>
</bean>

 这样配置也是可以的,但是注意在给你的action层注入的时候,就不能注入serverOnlineManager这个bean而要改为myBean,或者,依然使用serverOnlineManager,但需要在你的spring配置文件里加上:

    <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
 

最后是ehcache.xml的配置,没啥说的

<ehcache>

    <diskStore path="java.io.tmpdir"/>

    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        overflowToDisk="true"
        timeToIdleSeconds="120"
        timeToLiveSeconds="120"
        diskPersistent="false"
        diskExpiryThreadIntervalSeconds="120"/>
        
    <!-- See http://ehcache.sourceforge.net/documentation/#mozTocId258426 for how to configure caching for your objects -->

   <cache name="com.xxx.stat.serverOnline.namedQuery.query1"
        maxElementsInMemory="100000"
        eternal="false"
        timeToIdleSeconds="60"
        timeToLiveSeconds="60"
        overflowToDisk="true"
     />

</ehcache>
 

Spring文档里对ProxyFactoryBean的介绍------

像其它的 FactoryBean 实现一样, ProxyFactoryBean 引入了一个间接层。如果你定义一个名为 foo ProxyFactoryBean , 引用 foo 的对象看到的将不是 ProxyFactoryBean 实例本身,而是一个 ProxyFactoryBean 实现里 getObject() 方法所创建的对象。 这个方法将创建一个AOP代理,它包装了一个目标对象。

Spring文档里对BeanNameAutoProxyCreator的说明------

BeanNameAutoProxyCreator为名字匹配字符串或者通配符的bean自动创建AOP代理。”

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值