从 Spring 1.1.1 开始,
EHCache就作为一种通用缓存解决方案集成进 Spring。在一次实际使用EhCache作为缓存数据层缓存过程中,碰到了EhCache对象无法将Element保存到缓存中的问题,最终导致 HItCount总是为零,从而意味着缓存根本就没有起作用,无法达到预期效果,具体配置环境如下:
1.Spring使用3.0.5版本,其中对Ehcache的集成配置信息如下所示:
<!-- 引用ehCache的配置 -->
<bean id="defaultCacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
</bean>
<!-- 定义ehCache的工厂,并设置所使用的Cache name -->
<bean id="ehCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">
<property name="cacheManager">
<ref local="defaultCacheManager" />
</property>
<property name="cacheName" value="departCache" />
</bean>
2.ehcache.xml的配置情况如下所示 :
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<!—设置缓存文件 .data 的创建路径。
如果该路径是 Java 系统参数,当前虚拟机会重新赋值。
下面的参数这样解释:
user.home – 用户主目录
user.dir – 用户当前工作目录
java.io.tmpdir – 默认临时文件路径 -->
<diskStore path="java.io.tmpdir" />
<defaultCache eternal="false" maxElementsInMemory="1000"
overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0"
timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU" />
<!—缺省缓存配置。CacheManager 会把这些配置应用到程序中。
下列属性是 defaultCache 必须的:
maxInMemory - 设定内存中创建对象的最大值。
eternal - 设置元素(译注:内存中对象)是否永久驻留。如果是,将忽略超
时限制且元素永不消亡。
timeToIdleSeconds - 设置某个元素消亡前的停顿时间。
也就是在一个元素消亡之前,两次访问时间的最大时间间隔值。
这只能在元素不是永久驻留时有效(译注:如果对象永恒不灭,则
设置该属性也无用)。
如果该值是 0 就意味着元素可以停顿无穷长的时间。
timeToLiveSeconds - 为元素设置消亡前的生存时间。
也就是一个元素从构建到消亡的最大时间间隔值。
这只能在元素不是永久驻留时有效。
overflowToDisk - 设置当内存中缓存达到 maxInMemory 限制时元素是否可写到磁盘
上。
-->
<cache name="departCache" eternal="false" maxElementsInMemory="1000"
maxElementsOnDisk="1000" overflowToDisk="true" diskPersistent="false" timeToIdleSeconds="1440"
timeToLiveSeconds="2880" memoryStoreEvictionPolicy="FIFO" />
</ehcache>
3.在代码中采用手动去计算缓存key的方式来进行缓存,具体使用如下:
private List<AnalysisVO> execute(String sql) throws DaoException {
try {
String key=SystemUtil.encrypt(sql.toUpperCase());//md5值
Object obj = cache.get(key);
if (obj != null) {
return (List<AnalysisVO>) obj;
}
List<AnalysisVO> list = mapper.getAnalysisByYear(sql);
if (list != null)
cache.put(new Element(key, list));
cache.flush();
return list;
} catch (Exception k) {
return null;
}
}
4.问题
在使用过程中始终无法将Element对象写入到cache,从而导致缓存的命中率为0,无法让缓存达到初始目的,经过一段时间排查,最终发现是采用ehcache1.6版本的包在spring3.0.5版本下面存在一定的问秒,通过将依赖包更换为ehcache1.4.2,问题得到解决。