EhCache3使用说明

Maven导入ehcache相关包


<dependency>
    <groupId>org.ehcachegroupId>
    <artifactId>ehcacheartifactId>
    <version>3.8.1version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4jgroupId>
            <artifactId>slf4j-apiartifactId>
        exclusion>
    exclusions>
dependency>

<dependency>
    <groupId>org.slf4jgroupId>
    <artifactId>slf4j-reload4jartifactId>
    <version>2.0.6version>
dependency>

Java编码方式

官方文档地址:Ehcache 3.8_Getting Started


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 CQY
 * @version 1.0
 * @date 2023/2/18 11:46
 * @desc Ehcache 3.8 java代码配置
 **/
public class EhCache38TestJava01 {

    public static void main(String[] args) {
        try (CacheManager cacheManager =
                     // 1.静态方法org.ehcache.config.builders.CacheManagerBuilder.newCacheManagerBuilder返回一个新org.ehcache.config.builders.CacheManagerBuilder实例。
                     CacheManagerBuilder.newCacheManagerBuilder()
                             /*2. 使用构建器定义Cache别名为“preConfigured”的。cacheManager.build()当在实际实例上调用时将创建此缓存CacheManager。
                               第一个String参数是缓存别名,用于从CacheManager. 第二个参数org.ehcache.config.CacheConfiguration,用于配置Cache.
                               我们使用静态newCacheConfigurationBuilder()方法来org.ehcache.config.builders.CacheConfigurationBuilder创建默认配置。
                              */
                             .withCache("preConfigured", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10)))
                             // 3. 调用build()返回一个完全实例化但未初始化的,CacheManager我们可以使用。=> CacheManager使用初始化build(true)。
                             .build()) {
             /*
                4. 在使用之前CacheManager需要对其进行初始化,这可以通过以下两种方式之一完成:调用CacheManager.init()实例CacheManager,
                或调用CacheManagerBuilder.build(boolean init)布尔参数设置为 true 的方法。
             */
            cacheManager.init();

        /*
            5. 通过将别名、键类型和值类型传递给CacheManager. 例如,要获取在步骤 2 中声明的缓存,
            您需要它的alias="preConfigured",keyType=Long.class和valueType=String.class。为了类型安全,我们要求传入键和值类型。如果它们与我们期望的不同,
            则会在应用程序生命周期的早期CacheManager抛出。ClassCastException这可以防止Cache被随机类型污染。
         */
            Cache<Long, String> preConfigured =
                    cacheManager.getCache("preConfigured", Long.class, String.class);

        /*
            6. 可用于根据需要CacheManager创建新实例。Cache正如在第 2 步中一样,它需要传入一个别名和一个CacheConfiguration.
            实例化和完全初始化的Cache添加将通过 API 返回和/或访问CacheManager.getCache。
         */
            Cache<Long, String> myCache = cacheManager.createCache("myCache",
                    CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.heap(10)));

        /*
            7. 新添加的Cache现在可用于存储由键值对组成的条目。put 方法的第一个参数是键,第二个参数是值。
            请记住,键和值类型必须与CacheConfiguration. 此外,键必须是唯一的,并且只与一个值相关联。
         */
            myCache.put(1L, "da one!");
        /*
            8. 通过调用该方法从缓存中检索值cache.get(key)。它只接受一个参数,即键,并返回与该键关联的值。如果没有与该键关联的值,则返回 null。
         */
            String value = myCache.get(1L);
            System.out.println("value:" + value);

        /*
            9.我们可以CacheManager.removeCache(String)给定Cache。不仅CacheManager会删除它对 的引用 Cache,还会将其关闭。
            释放Cache所有本地持有的临时资源(例如内存)。对此的引用Cache变得不可用。
         */
            cacheManager.removeCache("preConfigured");
        /*
            10.为了释放 aCacheManager提供给Cache它管理的实例的所有临时资源(内存、线程……),
            您必须调用CacheManager.close(),这又会关闭Cache当时已知的所有实例。
            > CacheManager实现Closeable可以通过 try-with-resources 自动关闭。
         */
            // cacheManager.close();
        }
    }
}

XML配置方式

xml

<config
        xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
        xmlns='http://www.ehcache.org/v3'
        xsi:schemaLocation="http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core.xsd">

    
    <cache alias="foo">
        <key-type>java.lang.Stringkey-type>
        <value-type>java.lang.Stringvalue-type>
        <resources>
            
            <heap unit="entries">20heap>
            
            <offheap unit="MB">10offheap>
        resources>
    cache>

    
    <cache-template name="myDefaults">
        <key-type>java.lang.Longkey-type>
        <value-type>java.lang.Stringvalue-type>
        <heap unit="entries">200heap>
    cache-template>

    
    <cache alias="bar" uses-template="myDefaults">
        <key-type>java.lang.Numberkey-type>
    cache>

    
    <cache alias="simpleCache" uses-template="myDefaults"/>

config>

java代码


import cn.hutool.core.io.resource.ResourceUtil;
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.Configuration;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.xml.XmlConfiguration;

import java.net.URL;

/**
 * @author CQY
 * @version 1.0
 * @date 2023/2/18 11:46
 * @desc Ehcache 3.8 xmlj配置
 **/
public class EhCache38TestXml01 {

    public static void main(String[] args) {
        CacheManager myCacheManager = null;
        try {
            // hutool工具包获取类路径下的配置文件路径URL
            URL url = ResourceUtil.getResource("ehcache.xml");
            Configuration xmlConfig = new XmlConfiguration(url);
            myCacheManager = CacheManagerBuilder.newCacheManager(xmlConfig);
            myCacheManager.init();

            Cache<String, String> fooCache = myCacheManager.getCache("foo", String.class, String.class);
            fooCache.put("key1", "ABC");
            String value1 = fooCache.get("key1");
            System.out.println("value1:" + value1);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (myCacheManager != null) {
                myCacheManager.close();
            }
        }
    }
}

Ehcache分层缓存

分层缓存官方文件地址:Tiering options

package pub.qingyun.ehcache;

import cn.hutool.system.SystemUtil;
import lombok.extern.slf4j.Slf4j;
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.PersistentCacheManager;
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ExpiryPolicyBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.impl.config.store.disk.OffHeapDiskStoreConfiguration;
import org.junit.Test;

import java.io.File;
import java.time.Duration;

/**
 * @author CQY
 * @version 1.0
 * @date 2023/2/18 12:24
 * @desc Ehcache分层缓存
 * @see 分层缓存
 **/
@Slf4j
public class EhcacheTieringOptionsTestDemo {


    /**
     * 单层设置-堆
     */
    @Test
    public void test01() {
        // 堆上只允许 10 个条目。驱逐将在满时发生。
        ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10, EntryUnit.ENTRIES);
        // or 指定10个条目的快捷方法。
        ResourcePoolsBuilder.heap(10);
        // or 只允许 10 MB。驱逐将在满时发生。
        ResourcePoolsBuilder.newResourcePoolsBuilder().heap(10, MemoryUnit.MB);
    }

    /**
     * 单层设置-字节大小的堆
     * 对于除堆层之外的每一层,计算缓存的大小都相当容易。您或多或少地总结了包含序列化条目的所有字节缓冲区的大小。
     * 

* 当堆受大小而不是条目限制时,它有点复杂 */ @Test public void test02() { CacheConfiguration<Long, String> usesConfiguredInCacheConfig = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.newResourcePoolsBuilder() // 限制堆层用于存储键值对的内存量。调整对象大小会产生成本。 .heap(10, MemoryUnit.KB) // 设置仅供堆层使用。所以堆外根本不会使用它。 .offheap(10, MemoryUnit.MB)) .withSizeOfMaxObjectGraph(1000) /* 大小也可以通过 2 个额外的配置设置进一步限制:第一个指定遍历对象图时要遍历的最大对象数(默认值:), 第二个1000定义单个对象的最大大小(默认值Long.MAX_VALUE:无穷)。如果大小超过这两个限制中的任何一个,条目将不会存储在缓存中。 */ .withSizeOfMaxObjectSize(1000, MemoryUnit.B) .build(); CacheConfiguration<Long, String> usesDefaultSizeOfEngineConfig = CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.newResourcePoolsBuilder() .heap(10, MemoryUnit.KB)) .build(); CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder() .withDefaultSizeOfMaxObjectSize(500, MemoryUnit.B) .withDefaultSizeOfMaxObjectGraph(2000) .withCache("usesConfiguredInCache", usesConfiguredInCacheConfig) .withCache("usesDefaultSizeOfEngine", usesDefaultSizeOfEngineConfig) .build(true); } /** * 单层设置-堆外层 *

* 存储在堆外的数据必须进行序列化和反序列化——因此比堆慢。 * 因此,您应该支持堆外处理大量数据,而堆内处理会对垃圾收集产生过于严重的影响。 * -XX:MaxDirectMemorySize不要忘记根据您打算使用的堆外大小在 java options 中定义选项。 */ @Test public void test03() { // 堆外只允许 10 MB。驱逐将在满时发生。 ResourcePoolsBuilder.newResourcePoolsBuilder().offheap(10, MemoryUnit.MB); } /** * 单层设置-磁盘层 * 对于磁盘层,数据存储在磁盘上。磁盘越快、越专用,访问数据的速度就越快。 *

* 储在磁盘上的数据必须被序列化/反序列化并写入磁盘/从磁盘读取 - 因此比堆和堆外数据慢 */ @Test public void test04() { try (PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder() // 提供应存储数据的位置。 .with(CacheManagerBuilder.persistence(new File(SystemUtil.get("java.io.tmpdir"), "myData"))) .withCache("persistent-cache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, // 为缓存将使用的磁盘定义资源池。第三个参数是一个布尔值,用于设置磁盘池是否持久化。当设置为 true 时,池是持久的。 // 当使用带有 2 个参数的版本时disk(long, MemoryUnit),池不是持久的。 ResourcePoolsBuilder.newResourcePoolsBuilder().disk(10, MemoryUnit.MB, true)) // 定义一个OffHeapDiskStoreConfiguration指定所需段数的实例。磁盘存储被分成多个段,这些段提供并发访问,但也保存打开的文件指针。默认值为 16。 .withService(new OffHeapDiskStoreConfiguration(2)) ) .build(true)) { Cache<Long, String> cache = persistentCacheManager.getCache("persistent-cache", Long.class, String.class); // 将缓存持久化到硬盘中:C:\Users\*\AppData\Local\Temp\myData\file\threeTieredCache_99af5c58e82ee31980edbfc01dc4f362f30574b4 cache.put(1L, "stillAvailableAfterRestart"); // 存储在缓存中的所有值将在 JVM 重新启动后可用 log.info("key=[{}],value=[{}]", 1L, cache.get(1L)); } catch (Exception e) { e.printStackTrace(); } } /** * 多层设置 * 1.多层设置中必须始终有一个堆层。 * 2.您不能组合磁盘层和集群层。 * 3.层级应按金字塔方式调整大小,即金字塔较高的层级被配置为使用比较低层级更少的内存。 堆->堆外->磁盘 */ @Test public void test06() { try ( PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder() // 1. 如果您希望使用磁盘存储(如持久Cache实例),您必须向CacheManagerBuilder.persistence()静态方法提供一个数据应存储在磁盘上的位置。 .with(CacheManagerBuilder.persistence(new File(SystemUtil.get("java.io.tmpdir"), "myData"))) .withCache("threeTieredCache", CacheConfigurationBuilder.newCacheConfigurationBuilder(Long.class, String.class, ResourcePoolsBuilder.newResourcePoolsBuilder() // 堆 保存*个条目 .heap(10, EntryUnit.ENTRIES) // 堆外 .offheap(1, MemoryUnit.MB) // 磁盘定义一个持久资源池。它是持久的,因为它应该是(最后一个参数是true)。 .disk(20, MemoryUnit.MB, true) ) // 配置生存时间到期 .withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofDays(1))) ) .build(true); ) { Cache<Long, String> threeTieredCache = persistentCacheManager.getCache("threeTieredCache", Long.class, String.class); // 将缓存持久化到硬盘中:C:\Users\*\AppData\Local\Temp\myData\file\threeTieredCache_99af5c58e82ee31980edbfc01dc4f362f30574b4 threeTieredCache.put(1L, "stillAvailableAfterRestart"); // 存储在缓存中的所有值将在 JVM 重新启动后可用 log.info("key=[{}],value=[{}]", 1L, threeTieredCache.get(1L)); } } }

你可能感兴趣的:(ehcache,缓存)