最近做一个小项目,需要对一批数据进行缓存,且要求持久化到磁盘。使用ehcache非常简单和直观,一般来说只需要配置ehcache.xml文件,接着直接使用@Cacheable, @Cacheput, @CacheEvict即可。

三个注解的意思也很简单,这里就不说了。

ehchche.xml的配置非常简单和直观:

 1 <!--name:缓存名称-->
 2     <!--maxElementsInMemory:缓存最大个数-->
 3     <!--eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期-->
 4     <!--timeToIdleSeconds:置对象在失效前的允许闲置时间(单位:秒),仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大-->
 5     <!--timeToLiveSeconds:缓存数据的生存时间(TTL),也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间-->
 6     <!--overflowToDisk:内存不足时,是否启用磁盘缓存-->
 7     <!--maxElementsOnDisk:设置成0 表示硬盘中最大缓存对象数无限大-->
 8     <!--diskPersistent:设置成true表示缓存虚拟机重启期数据磁盘存储是否在虚拟机重启后持续存在-->
 9     <cache name="appdsCache"
10            maxElementsInMemory="0"
11            eternal="true"
12            maxElementsOnDisk="10000000"
13            overflowToDisk="true"
14            diskPersistent="true"
15            memoryStoreEvictionPolicy="LRU">
16         <!--<persistence strategy="localRestartable" synchronousWrites="false"/>-->
17     </cache>

但是在使用过程中遇到了两个小问题,下面简单的做个记录。

1. 在类中写了一个带有缓存注解的方法,然后在一个普通方法中调用了这个缓存函数,则缓存功能不再生效。如下:

@EnableCaching
class A implements IA{public String funA(){return funB();      }  @Cacheablepublic String funB(){...}
}

其实这和Spring的对象注入机制有关,例如,当外部通过@Autowired注解得到一个A类的对象时,其实得到的是一个spring包装过的代理对象。

当调用a.funB()时,实际调用的是spring的proxy对象中的funB()方法,该方法内置了cache机制,在cache检查后就会调用实际的a对象中的funA方法。

同理当调用a.funA()时,也是先调用spring的proxy对象中的funA()方法,经过检查和资源分配等步骤后,会调用实际的a对象中的funA()方法,但是当在实际的A类对象中再调用funB()时,不会触发cache机制,因为此时调用的不是SpringCacheProxy对象,而是一个实际的A类对象,所以不会触发cache机制。

如果深入研究Spring完成注入和AOP编程实现的原理,可以发现动态代理是很重要的一个技术。目前Spring的动态代理主要是通过CGLib来实现的。

那么这个问题如何解决呢?有两种思路:

(1) 拆分为两个类来实现。即将funA()和funB()写在两个类中。

(2) 在类中注入自身实例。如下:

@EnableCaching
@Service(value="a")
class A implements IA{@Resource(name="a")private IA a; public String funA(){return a.funB();      }  @Cacheablepublic String funB(){...}}

第二种方法亲测有效~~

不管怎样,都要记住如下原则:同一个类中的注解方法互相调用时,注解机制可能是无效的。

2. (在idea中点击红色按钮关闭程序时) 持久化到磁盘的数据无法恢复。

原因如下:ehcache和其它缓存类似,需要flush或shutdown后才会持久化到磁盘

     会生成.data 的数据文件和 .index 的索引文件,方便重启恢复。

       ehcache恢复数据是根据.index索引文件来进行数据恢复的。

       当程序再次启动的时候,ehcache的一个方法会将.data文件和.index文件的修改时间进行比较,如果不符合直接将.index文件删除。

一般来说,以下两种情况,会自动调用shutdown()函数:

(1) 调用System.exit(),或最后一个非守护线程退出。

(2) 虚拟机停止运行。例如在命令行中执行CTRL+C,这会导致kill -SIGTERM pid 或kill -15 pid。

而在idea中点击红色按钮时,属于非正常关闭,导致shutdown()未能执行,猜测执行的是类似kill-9直接杀死进程的方法,而不是kill-15比较安全的关闭。

官网建议是最好是在程序关闭之前显式地调用shutdown()函数,但是实际实践中,就算是显式调用了shutdown(),要是在程序运行到一半时点击idea的红色关闭按钮,缓存还是会失效。。

在我看来最安全的方法就是把程序打成jar包运行,用CTRL+C在命令行终止程序,就算此时程序并没有执行完,shutdown()也会执行。

使用EHCache需要注意的几个问题(转)相关推荐

  1. (转)使用 Spring缓存抽象 支持 EhCache 和 Redis 混合部署

    背景:最近项目组在开发本地缓存,其中用到了redis和ehcache,但是在使用注解过程中发现两者会出现冲突,这里给出解决两者冲突的具体方案. spring-ehcache.xml配置: <?x ...

  2. ehcache 简介

    hCache 是一个纯Java的进程内缓存框架,具有快速.精干等特点,是Hibernate中默认的CacheProvider. 下图是 Ehcache 在应用程序中的位置: ehcache部署起来很简 ...

  3. idea配置echache.xml报错Cannot resolve file 'ehcache.xsd'

    解决方法: 打开settings->languages&frameworks->schemas and dtds ,添加地址 http://ehcache.org/ehcache. ...

  4. ehcache导致Tomcat重启出错

    最近使用ehcache出现了问题,只要在配置文件中打开缓存,Tomcat在重启时就会报内存溢出异常.按说ehcache自己开启的资源,应该自己关闭才是.经查阅资料发现,需要在web.xml中配置一个监 ...

  5. Ehcache 3.0发布,修补了API并支持非堆存储

    Terracotta发布了分布式缓存技术Ehcache的3.0版本,支持了一些重要的新特性.首先,它的API进行了重构,现在使用了Java的泛型.性能也有所提升,同时还增加了对javax.cache ...

  6. mybatis整合ehcache

    ehcache是一个分布式缓存框架. 1  分布缓存 我们系统为了提高系统并发,性能.一般对系统进行分布式部署(集群部署方式) 不使用分布缓存,缓存的数据在各各服务单独存储,不方便系统 开发.所以要使 ...

  7. EhCache的特性

    一.特性一览 来自官网,简单翻译一下: 1.快速轻量 过去几年,诸多测试表明Ehcache是最快的Java缓存之一. Ehcache的线程机制是为大型高并发系统设计的. 大量性能测试用例保证Ehcac ...

  8. Ehcache配置参数详解

    ehcache配置参数详解 <?xml version="1.0" encoding="UTF-8"?><ehcache><dis ...

  9. ehcache + spring 整合以及配置说明 ,附带整合问题 (已解决)

    新做的项目,因为流量不大 就是一个征信平台,高峰流量不多,但缓存是必须的,cache到server上就可以,不需要额外的memcache.redis之类的东西. 但是遇到一个大坑,事情是这样的: 通过 ...

  10. Spring Boot教程(一)注解配置与EhCache使用

    2019独角兽企业重金招聘Python工程师标准>>> 快速入门 首先,下载样例工程chapter3-2-2.本例通过spring-data-jpa实现了对User用户表的一些操作, ...

最新文章

  1. 从小护士到微软中国总经理,逆风飞扬的“打工皇后”吴士宏的传奇人生
  2. Vue项目碰到‘webpack-dev-server’不是内部或外部命令,也不是可运行的程序或批处理文件报错...
  3. 开机启动脚本/etc/init.d/rcS
  4. python的类程序的结构_Python程序员学习路径之数据结构篇
  5. 在mac OSX中安装启动zookeeper
  6. linq 查询的结果会开辟新的内存吗?
  7. c语言程序设计实践课选题,c语言程序设计实践实验题目
  8. unity 存档插件_【Unity消息】5月1日到5月15日 Unity资源商店大促
  9. 拼接 结果集_JUST技术:利用轨迹拼接分析实时可达区域|技术前沿
  10. 阿里云科学家入选计算机顶会 HPCA 名人堂,他是什么来头?
  11. 页面字符编码不一致的处理
  12. C# 让你解决方案乱七八糟的DLL放入指定文件夹
  13. HDU 4511 小明系列故事——女友的考验 (AC自动机 + DP)题解
  14. 选择排序 简单选择排序 直接选择排序的区别
  15. PDF文件的书签批量自动导入和导出 PDFBookmark-Exchanger
  16. Scintilla的高级技法
  17. 照片如何换背景?分享两个快速换背景的方法
  18. 有n个人围成一圈,顺序排号。从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来第几号的那位。(java)
  19. Python自动化 requests 库:发送 form-data 格式的 http 请求
  20. 西宁市财政局容灾备份项目

热门文章

  1. java中long类型转换为int类型
  2. Wampserver之 virtualHost
  3. 012.Adding a New Field --【添加一个新字段】
  4. mac搭建本地svn
  5. Magento--判断checkout中是否使用了coupon code
  6. 被LTRIM(RTRIM())害死了,差点
  7. C# 多线程控制 通讯 和切换
  8. autoresetevent java_[原创]AutoResetEvent, ManualResetEvent的Java模拟
  9. MQTT 物联网协议
  10. 安卓APP_ Fragment(3)—— Fragment的生命周期