EhCache 简单入门

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

主要特性

1、快速、简单、支持多种缓存策略
2、支持内存和磁盘缓存数据,因此无需担心容量问题
3、缓存数据会在虚拟机重启的过程中写入磁盘
4、可以通过RMI、可插入API等方式进行分布式缓存(比较弱)
5、具有缓存和缓存管理器的侦听接口
6、支持多缓存管理器实例,以及一个实例的多个缓存区域
7、提供Hibernate的缓存实现

EhCache 架构图

适用场景

1、单个应用或者对缓存访问要求很高的应用
2、简单的共享可以,但是不适合涉及缓存恢复、大数据缓存
3、大型系统,存在缓存共享、分布式部署、缓存内容大不适合使用
4、在实际工作中,更多是将Ehcache作为与Redis配合的二级缓存


2.x 版本用法

  • maven 引用
    <dependencies>
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache</artifactId>
            <version>2.10.6</version>
        </dependency>
    </dependencies>
  • resources目录下创建ehcache.xml
    这样在初始化CacheManager的时候会自动加载,这个名字的文件,具体可以查看源码。

ehcache.xml自动加载的源码

   public static Configuration parseConfiguration() throws CacheException {
       ClassLoader standardClassloader = Thread.currentThread().getContextClassLoader();
       URL url = null;
       if (standardClassloader != null) {
           url = standardClassloader.getResource("/ehcache.xml");
       }

       if (url == null) {
           url = ConfigurationFactory.class.getResource("/ehcache.xml");
       }

       if (url != null) {
           LOG.debug("Configuring ehcache from ehcache.xml found in the classpath: " + url);
       } else {
           url = ConfigurationFactory.class.getResource("/ehcache-failsafe.xml");
           LOG.warn("No configuration found. Configuring ehcache from ehcache-failsafe.xml  found in the classpath: {}", url);
       }

       Configuration configuration = parseConfiguration(url);
       configuration.setSource(ConfigurationSource.getConfigurationSource());
       return configuration;
   }

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <!-- 指定一个文件目录,当EhCache把数据写到硬盘上时,将把数据写到这个文件目录下 -->
    <diskStore path="java.io.tmpdir"/>

    <!--
    cache元素的属性:
        name:缓存名称
        maxElementsInMemory:内存中最大缓存对象数
        maxElementsOnDisk:硬盘中最大缓存对象数,若是0表示无穷大
        eternal:true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false
        overflowToDisk:true表示当内存缓存的对象数目达到了maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。
        diskSpoolBufferSizeMB:磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。
        diskPersistent:是否缓存虚拟机重启期数据
        diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认为120秒
        timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地处于空闲状态
        timeToLiveSeconds:设定对象允许存在于缓存中的最长时间,以秒为单位。当对象自从被存放到缓存中后,如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义
        memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。可选策略有:LRU(最近最少使用淘汰策略,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
    -->

    <!-- 设定缓存的默认数据过期策略 -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="10"
            timeToLiveSeconds="20"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"/>

    <cache name="simpleCache"
           maxElementsInMemory="1000"
           eternal="false"
           overflowToDisk="true"
           timeToIdleSeconds="10"
           timeToLiveSeconds="20"/>

</ehcache>
  • logging 配置

maven

        <!--  logging  -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.5</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.11.0</version>
        </dependency>
        <!-- log4j-core  -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.11.0</version>
        </dependency>
        <!--  log4j-web  -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-web</artifactId>
            <version>2.11.0</version>
        </dependency>
        <!--  end of logging  -->

log4j.properties

#log4j输出选项
#log4j.rootLogger=info,stdout,file
log4j.rootLogger=INFO,stdout

#log4j.logger.net.sf.ehcache=DEBUG
#输出到控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.ImmediateFlush=true   
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout   
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH\:mm\:ss,SSS}_%t method\:%l%n%m%n
#写入到根目录
#log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
#log4j.appender.file.file=${logpath}/logs/log_info.log
#log4j.appender.file.encoding=UTF-8
#log4j.appender.file.DatePattern='.'yyyy-MM-dd
#log4j.appender.file.layout=org.apache.log4j.PatternLayout
#log4j.appender.file.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH\:mm\:ss,SSS}_%t method\:%l%n%m%n
  • 测试代码
package cn.lazyfennec.encache;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

/**
 * @Author: Neco
 * @Description: EhCache Test 2.X 版本
 * @Date: create in 2022/6/10 16:43
 */
public class TestEhCacheCache2 {
    public static void main(String[] args) {
        //初始化Ehcahce对象
        CacheManager cacheManager = new CacheManager();
        //加载自定义cache对象
        Cache cache = cacheManager.getCache("simpleCache");
        //把集合放入缓存  存放键值对集合类似map
        cache.put(new Element("user", "zhangsan"));
        //取出集合根据key获取值
        System.out.println("key=user value=:" + cache.get("user").getObjectValue());
        //更新集合的key=user的值
        cache.put(new Element("user", "lisi"));
        System.out.println("key=user value=:" + cache.get("user").getObjectValue());
        //获取缓存中的原素个数
        System.out.println("集合个数:" + cache.getSize());
        //移除cache某个值
        cache.remove("user");
        System.out.println("集合个数:" + cache.getSize());
        // 关闭当前CacheManager对象
        cacheManager.shutdown();
    }

}
  • 运行结果
key=user value=:zhangsan
key=user value=:lisi
集合个数:1
集合个数:0

3.x 版本

截止本文编写的时候,最新的版本已经发布到3.10版本,具体看上去实现起来也更为简单,但是其中的一些方法使用起来变化还是不小的,一个具体的简单例子如下:

package cn.lazyfennec.encache;

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;

/**
 * @Author: Neco
 * @Description: EhCache Test 3.X 版本
 * @Date: create in 2022/6/10 16:43
 */
public class TestEhCacheCache3 {
    public static void main(String[] args) {
        // 配置和构建缓存管理器
        CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                .withCache("preConfigured",
                        CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10)))
                .build();
        // 初始化
        cacheManager.init();
        // 根据配置实例化一个缓存
        Cache<Long, String> preConfigured = cacheManager.getCache("preConfigured", Long.class, String.class);
        Cache<Long, String> myCache = cacheManager.createCache("myCache",
                CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10)));

        myCache.put(1L, "da one!");
        String value = myCache.get(1L);
        System.out.println(value);
        cacheManager.removeCache("preConfigured");

        cacheManager.close();
    }

}

官方参考文档


如果觉得有收获就点个赞吧,更多知识,请点击关注查看我的主页信息哦~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容