EhCache 简单入门

作者: 右耳菌 | 来源:发表于2022-06-10 18:11 被阅读0次

    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();
        }
    
    }
    

    官方参考文档


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

    相关文章

      网友评论

        本文标题:EhCache 简单入门

        本文链接:https://www.haomeiwen.com/subject/bqvmmrtx.html