Spring整合Ehcache缓存

EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvide。

第一步:添加项目相关jar包(下面配置只写明了ehcache其它spring相关的jar请参考其它网上资料添加)

		   <dependency>
				<groupId>net.sf.ehcache</groupId>
				<artifactId>ehcache-core</artifactId>
				<version>2.6.11</version>
			</dependency>

第二步:添加ehcache.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <diskStore path="java.io.tmpdir" />
    <defaultCache maxElementsInMemory="10000" eternal="false"
                  timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" />

    <cache name="authorizationCache"
           maxEntriesLocalHeap="2000"
           eternal="false"
           timeToIdleSeconds="3600"
           timeToLiveSeconds="0"
           overflowToDisk="false"
           statistics="true">
    </cache>
</ehcache>


第三步:在Spring(SpringMVC)的配置文件中添加如下配置:

对象缓存就是将查询的数据,添加到缓存中,下次再次查询的时候直接从缓存中获取,而不去数据库中查询。

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

<context:component-scan base-package="com.tuzki"/> 
<!-- 配置eh缓存管理器 -->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" 
p:configLocation="classpath:ehcache.xml" p:shared="true" />
 
<!-- 配置一个简单的缓存工厂bean对象 -->
<bean id="simpleCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
    <property name="cacheManager" ref="cacheManager" />
    <!-- 使用缓存 关联ehcache.xml中的缓存配置 -->
    <property name="cacheName" value="authorizationCache" />
</bean>
 
<!-- 配置一个缓存拦截器对象,处理具体的缓存业务 -->
<bean id="methodCacheInterceptor" class="com.tuzki.controllers.admin.MethodCacheInterceptor">
    <property name="cache" ref="simpleCache"/>
</bean>
 
<!-- 参与缓存的切入点对象 (切入点对象,确定何时何地调用拦截器) -->
<bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
    <!-- 配置缓存aop切面 -->
    <property name="advice" ref="methodCacheInterceptor" />
    <!-- 配置哪些方法参与缓存策略 -->
    <!--  
        .表示符合任何单一字元                  
        ###  +表示符合前一个字元一次或多次                  
        ###  *表示符合前一个字元零次或多次                  
        ###  \Escape任何Regular expression使用到的符号                  
    -->                 
    <!-- .*表示前面的前缀(包括包名) 表示print方法-->
    <property name="patterns">
        <list>
            <value>com.*.*RestService*\.*get.*</value>
            <value>com.*.*RestService*\.*search.*</value>
        </list>
    </property>
</bean>


补充1:配置中的 p:configLocation="classpath:ehcache.xml" p:shared="true" 很重要,因为你在使用Ehcache的时候,通常也使用了其它框架(mybatis、shiro等),如果没有上面的配置可能会报”配置文件ehcache.xml找不到“和”cacheManager对象创建失败“等错误。

补充2:Ehcache是一个灵巧的缓存小数据量的方案,按照配置可以正常生成cacheManager对象之后,也可以给其它常见框架使用,比如下面的shiro框架

    <bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
        <property name="realm" ref="myRealm"/>
        <property name="cacheManager" ref="cacheManager" />
    </bean>

第四步:实现缓存具体处理逻辑代码

package com.tuzki.controllers.admin;

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;

/** 
 *
 * @author Horace 
 * @version 创建时间:2015年12月1日 下午3:44:36 
 *  
 */
public class MethodCacheInterceptor implements MethodInterceptor, InitializingBean {

	private static final Logger logger = Logger.getLogger(MethodCacheInterceptor.class);
	
	private Cache cache;
	 
    public void setCache(Cache cache) {
        this.cache = cache;
    }
    
	@Override
	public void afterPropertiesSet() throws Exception {
		// TODO Auto-generated method stub
		logger.info(cache + " A cache is required. Use setCache(Cache) to provide one.");
	}

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		// TODO Auto-generated method stub
		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) {
                logger.info(cacheKey + "加入到缓存: " + cache.getName());
                // 调用实际的方法
                result = invocation.proceed();
                element = new Element(cacheKey, (Serializable) result);
                cache.put(element);
            } else {
                logger.info(cacheKey + "使用缓存: " + cache.getName());
            }
        }
        return  element.getObjectValue();
    }
	
	/**
     * <b>function:</b> 返回具体的方法全路径名称 参数
     * @author hoojo
     * @createDate 2012-7-2 下午06:12:39
     * @param targetName 全路径
     * @param methodName 方法名称
     * @param arguments 参数
     * @return 完整方法名称
     */
    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();
    }

}

第五步:测试并部署

按照你的配置就行触发测试,通过查看日志就能判断ehcache环境生效没有。


参考文献:

1.http://www.cnblogs.com/hoojo/archive/2012/07/12/2587556.html  Ehcache 整合Spring 使用页面、对象缓存  

2.http://haohaoxuexi.iteye.com/blog/2123030   Spring使用Cache  

3.http://www.blogjava.net/crazycy/archive/2014/07/13/415740.html  SpringMVC+MyBatis - 9 Spring的EnCache(Shiro Cache的解决方案是基于这个文章的)

猜你喜欢

转载自blog.csdn.net/tongdao/article/details/50207993