`
lastsoul
  • 浏览: 32943 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

ehcache缓存方法返回结果(一)-MethodCacheInterceptor

    博客分类:
  • WEB
 
阅读更多
对象缓存就是将查询的数据,添加到缓存中,下次再次查询的时候直接从缓存中获取,而不去数据库中查询。

对象缓存一般是针对方法、类而来的,结合Spring的Aop对象、方法缓存就很简单。这里需要用到切面编程,用到了Spring的MethodInterceptor

代码如下:
package com.last.cache.ehcache.filter;
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.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
 
public class MethodCacheInterceptor implements MethodInterceptor, InitializingBean {
 
    private static final Logger log = Logger.getLogger(MethodCacheInterceptor.class);
    
    private Cache cache;
 
    public void setCache(Cache cache) {
        this.cache = cache;
    }
 
    public void afterPropertiesSet() throws Exception {
        log.info(cache + " A cache is required. Use setCache(Cache) to provide one.");
    }
 
    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);
        Element element = null;
        synchronized (this) {
            element = cache.get(cacheKey);
            if (element == null) {
                log.info(cacheKey + "加入到缓存: " + cache.getName());
                // 调用实际的方法
                result = invocation.proceed();
                element = new Element(cacheKey, (Serializable) result);
                cache.put(element);
            } else {
                log.info(cacheKey + "使用缓存: " + cache.getName());
            }
        }
        return element.getValue();
    }
 
    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();
    }
}


web.xml
<context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>
        	classpath:spring-*.xml
        </param-value>  
    </context-param> 
	<listener>  
        <listener-class>  
         org.springframework.web.context.ContextLoaderListener 
        </listener-class>  
    </listener>  


spring-ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
	xmlns:task="http://www.springframework.org/schema/task" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-3.0.xsd
		http://www.springframework.org/schema/tx
		http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
		http://www.springframework.org/schema/util
		http://www.springframework.org/schema/util/spring-util-3.0.xsd
		http://www.springframework.org/schema/task
		http://www.springframework.org/schema/task/spring-task-3.0.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
     	http://www.springframework.org/schema/cache 
     	http://www.springframework.org/schema/cache/spring-cache.xsd">

	<context:component-scan base-package="com.last" />

	<!-- 配置eh缓存管理器 -->
	<bean id="mycacheManager"
		class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:shared="true" />

	<!-- 配置一个简单的缓存工厂bean对象 -->
	<bean id="simpleCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
		<property name="cacheManager" ref="mycacheManager" />
		<!-- 使用缓存 关联ehcache.xml中的缓存配置 -->
		<property name="cacheName" value="mobileCache" />
	</bean>

	<!-- 配置一个缓存拦截器对象,处理具体的缓存业务 -->
	<bean id="cacheAdvice" class="com.last.cache.ehcache.filter.MethodCacheInterceptor">
		<property name="cache" ref="simpleCache" />
	</bean>


	<aop:config proxy-target-class="false">
		<!-- "execution(* com.last.service.*.*(..))" -->
		<aop:pointcut id="pc"
			expression="(execution(* com.last.service.impl.*.find*(..))) or (execution(* com.last.service.impl2.*.find*(..)))" />
		<aop:advisor pointcut-ref="pc" advice-ref="cacheAdvice" />
	</aop:config>
</beans>


AOP的配置展示了如何使用多个表达式,有一点要注意,过滤包名下的任意方法要多一个星,如:execution(* com.last.service.impl.*.find*(..))  表示impl下及子包下的方法,并不能去掉这个星,变成execution(* com.last.service.impl.find*(..))  ,表示impl下的方法也不能改成上面这样。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics