在Spring中通过EHCache实现缓存,必须手动缓存或者通过AOP进行缓存实现。通过采用SpringModules进行缓存是EHCache不必进行自动缓存,由SpringMoudles提供拦截器实现,简化开发的。实现如下:
1.EHCache的配置如下:
<ehcache> <diskStore path="java.io.tmpdir" /> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="2" timeToLiveSeconds="5" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <cache name="testCache" maxElementsInMemory="10000" maxElementsOnDisk="1000" eternal="false" overflowToDisk="false" diskSpoolBufferSizeMB="20" timeToIdleSeconds="60" timeToLiveSeconds="3600" memoryStoreEvictionPolicy="LFU" /> </ehcache>
2.Spring中配置如下
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"> <!-- Using a EHCache cache manager --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <!--EHCache cacheManager <property name="cacheManagerName" value="mainCache"/> --> <property name="configLocation" value="classpath:ehcache.xml" /> </bean> <!-- 使用Spring Modules对 EhCache的封装 --> <bean id="cacheProviderFacade" class="org.springmodules.cache.provider.ehcache.EhCacheFacade"> <property name="cacheManager" ref="cacheManager" /> </bean> <!-- 配置 方法 拦截器 --> <!-- 缓存拦截器 --> <bean id="cachingInterceptor" class="org.springmodules.cache.interceptor.caching.MethodMapCachingInterceptor"> <property name="cacheProviderFacade" ref="cacheProviderFacade" /> <property name="cachingModels"> <!-- 进行cache缓存 --> <props> <!-- 所有TicketService对象中,以get开头的方法都将进行缓存 --> <prop key="com.easyway.ecache.service.TicketService.get*">cacheName=testCache</prop> </props> </property> </bean> <!-- 缓存刷新拦截器 --> <bean id="flushingInterceptor" class="org.springmodules.cache.interceptor.flush.MethodMapFlushingInterceptor"> <property name="cacheProviderFacade" ref="cacheProviderFacade" /> <property name="flushingModels"> <!-- 进行cache刷新(清除) --> <props> <prop key="com.easyway.ecache.service.TicketService.set*">cacheNames=testCache</prop> </props> </property> </bean> <!-- 相关的服务 --> <bean id="ticketService" class="com.easyway.ecache.service.TicketService"></bean> <!-- 配置 基于BeanName规则的动态代理封装 --> <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator"> <!-- 设置拦截的bean名称 --> <property name="beanNames"> <list> <value>ticketService</value> </list> </property> <!-- 设置拦截器的名称 --> <property name="interceptorNames"> <list> <value>cachingInterceptor</value> <value>flushingInterceptor</value> </list> </property> </bean> </beans>
仔细观察可知道上面带颜色的类其实是几个采用AOP实现的拦截器而已。
3.编写测试服务类
package com.easyway.ecache.service; import java.util.List; /** * 对其所有的以get* 方式命令的方法,进行缓存处理。当调用set* 命令时,需要其删除缓存 * @author longgangbai * */ @SuppressWarnings("unchecked") public class TicketService { /** * 需要缓存的集合 */ private List ticketList; /** * 需要缓存的服务名称 */ private String serviceName; public String getServiceName() { return serviceName; } public void setServiceName(String serviceName) { this.serviceName = serviceName; } public List getTicketList() { return ticketList; } public void setTicketList(List ticketList) { this.ticketList = ticketList; } /** * 修改的服务端名称备注但是不缓存 * @param serviceName */ public void changesetServiceName(String serviceName) { this.serviceName = serviceName; } }
4.测试用例如下
package com.easyway.ecache.service; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * 测试SpringModule EhCache 的整合的应用 * @author longgangbai * */ public class Test { public static void main(String[] args) { ApplicationContext ctx=new ClassPathXmlApplicationContext("classpath*:applicationContext.xml"); TicketService ticketSrv=(TicketService)ctx.getBean("ticketService"); String srvName0=ticketSrv.getServiceName(); //获取初始化服务端名称 System.out.println("srvName0="+srvName0); //设置存储的名称 ticketSrv.setServiceName("ticketService"); srvName0=ticketSrv.getServiceName(); //获取服务端名称 System.out.println("srvName1="+srvName0); //修改服务名称但是不缓存 ticketSrv.changesetServiceName("serviceName"); srvName0=ticketSrv.getServiceName(); //获取服务端名称来源自缓存注意观察 System.out.println("srvName2="+srvName0); // //srvName0=null //srvName1=ticketService //srvName2=ticketService } }
5.测试结果如下:
srvName0=null
srvName1=ticketService
srvName2=ticketService
6.采用的类库如下:
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="lib" path="src/spring.jar"/>
<classpathentry kind="lib" path="src/spring-modules-cache.jar"/>
<classpathentry kind="lib" path="src/ehcache-1.6.0-beta4.jar"/>
<classpathentry kind="lib" path="src/commons-lang.jar"/>
<classpathentry kind="lib" path="src/commons-logging.jar"/>
<classpathentry kind="lib" path="src/oro-2.0.7.jar"/>
<classpathentry kind="lib" path="src/cglib-nodep-2.1_3.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>