JAVA中使用springBoot和Ehcache3.X无xml配置和xml配置

ehcache3.3官方文档地址

我用的是springBoot和Ehcache3.3

1.在maven的pom.xml导入ehcache3.3.0依赖

<!-- Ehcache 缓存-->
<dependency>
    <groupId>org.ehcache</groupId>
    <artifactId>ehcache</artifactId>
    <version>3.3.0</version>
</dependency>

一、无xml版本配置

1.创建一个EhcacheUtil.java类用来保存配置

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.CacheConfiguration;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;
import org.ehcache.expiry.Duration;
import org.ehcache.expiry.Expirations;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Configuration;

import java.io.FileNotFoundException;
import java.util.concurrent.TimeUnit;

/**
 * ClassName: EhcacheConfig
 * Description: Ehcache配置
 * Author: johnnybro@qq.com
 * Date: 2018/05/18 14:30:36
 */
@Configuration
@EnableCaching
public class EhcacheUtil {
    private static CacheManager cacheManager;
    /**
     * 初始化Ehcache缓存对象
     */
    public EhcacheUtil() {
        System.out.println("[Ehcache配置初始化<开始>]");

        // 配置默认缓存属性
        CacheConfiguration<String, String> cacheConfiguration = CacheConfigurationBuilder.newCacheConfigurationBuilder(
                // 缓存数据K和V的数值类型
                // 在ehcache3.3中必须指定缓存键值类型,如果使用中类型与配置的不同,会报类转换异常
                String.class, String.class,
                ResourcePoolsBuilder
                        .newResourcePoolsBuilder()
                        //设置缓存堆容纳元素个数(JVM内存空间)超出个数后会存到offheap中
                        .heap(1000L,EntryUnit.ENTRIES)
                        //设置堆外储存大小(内存存储) 超出offheap的大小会淘汰规则被淘汰
                        .offheap(100L, MemoryUnit.MB)
                        // 配置磁盘持久化储存(硬盘存储)用来持久化到磁盘,这里设置为false不启用
                        .disk(500L, MemoryUnit.MB, false)
        ).withExpiry(Expirations.timeToLiveExpiration(
                //设置缓存过期时间
                Duration.of(30L, TimeUnit.SECONDS))
        ).withExpiry(Expirations.timeToIdleExpiration(
                //设置被访问后过期时间(同时设置和TTL和TTI之后会被覆盖,这里TTI生效,之前版本xml配置后是两个配置了都会生效)
                Duration.of(60L, TimeUnit.SECONDS))
        )
        // 缓存淘汰策略 默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
        // 这块还没看
        /*.withEvictionAdvisor(
                new OddKeysEvictionAdvisor<Long, String>())*/
        ).build();
        // CacheManager管理缓存
        cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
        // 硬盘持久化地址
        .with(CacheManagerBuilder.persistence("D:/ehcacheData"))
        // 设置一个默认缓存配置
        .withCache("defaultCache", cacheConfiguration)
        //创建之后立即初始化
        .build(true);

        System.out.println("[Ehcache配置初始化<完成>]");
    }
}

2.在main方法中进行测试

1)测试heap配置

修改配置

//设置缓存堆容纳元素个数(JVM内存空间)
 .heap(1L, EntryUnit.ENTRIES)
//设置堆外储存大小(内存存储)
//.offheap(100L, MemoryUnit.MB)
// 配置磁盘持久化储存(硬盘存储)
//.disk(500L, MemoryUnit.MB, false)
public static void main(String[] args) throws InterruptedException, FileNotFoundException {
    // 初始化Ehcache对象    
    new EhcacheUtil();
    // 获取初始化的缓存对象
    Cache<String, String> mineCache = cacheManager.getCache("defaultCache", String.class, String.class);
    // 创建测试内容
    StringBuilder strTemp = new StringBuilder("测试");
    // 存入第1条数据
    mineCache.put("key", strTemp.toString());
    // 取出并输出
    System.out.println("key:" + mineCache.get("key"));
    strTemp = new StringBuilder("测试2");
    // 存入第2条数据
    mineCache.put("key2", strTemp.toString());
    // 取出并输出
    System.out.println("key2:" + mineCache.get("key2"));
    // 取出并输出第一条数据,因为heap的个数设置为1所以当存入第2条数据时,第一条会被淘汰
    System.out.println("key1:" + mineCache.get("key1"));
    // 关闭ehcache
    cacheManager.close();
}
//控制台输出的结果
Connected to the target VM, address: '127.0.0.1:61909', transport: 'socket'
[Ehcache配置初始化<开始>]
13:41:55.435 [main] DEBUG org.ehcache.core.internal.service.ServiceLocator - Starting 17 Services...
13:41:55.465 [main] DEBUG org.ehcache.impl.persistence.DefaultLocalPersistenceService - RootDirectory Locked
13:41:55.475 [main] DEBUG org.ehcache.core.internal.service.ServiceLocator - All Services successfully started, 17 Services in 40ms
13:41:55.485 [main] DEBUG org.ehcache.core.EhcacheManager - Creating Cache 'defaultCache' in EhcacheManager.
13:41:55.485 [main] DEBUG org.ehcache.impl.internal.spi.serialization.DefaultSerializationProvider - Serializer for <java.lang.String> : org.ehcache.impl.serialization.StringSerializer@52e677af
13:41:55.485 [main] DEBUG org.ehcache.impl.internal.spi.serialization.DefaultSerializationProvider - Serializer for <java.lang.String> : org.ehcache.impl.serialization.StringSerializer@7d68ef40
13:41:55.495 [main] DEBUG org.ehcache.impl.internal.spi.copy.DefaultCopyProvider - Copier for <java.lang.String> : org.ehcache.impl.copy.IdentityCopier@475e586c
13:41:55.495 [main] DEBUG org.ehcache.impl.internal.spi.copy.DefaultCopyProvider - Copier for <java.lang.String> : org.ehcache.impl.copy.IdentityCopier@657c8ad9
13:41:55.685 [main] DEBUG class org.ehcache.core.Ehcache-defaultCache - Initialize successful.
13:41:55.685 [main] INFO org.ehcache.core.EhcacheManager - Cache 'defaultCache' created in EhcacheManager.
13:41:55.685 [main] DEBUG org.ehcache.core.EhcacheManager - Initialize successful.
[Ehcache配置初始化<完成>]
key:测试
key2:测试2
key1:null
Disconnected from the target VM, address: '127.0.0.1:61909', transport: 'socket'
13:41:55.695 [main] DEBUG class org.ehcache.core.Ehcache-defaultCache - Close successful.
13:41:55.695 [main] INFO org.ehcache.core.EhcacheManager - Cache 'defaultCache' removed from EhcacheManager.
13:41:55.695 [main] DEBUG org.ehcache.core.internal.service.ServiceLocator - Stopping 17 Services...
13:41:55.695 [main] DEBUG org.ehcache.impl.persistence.DefaultLocalPersistenceService - RootDirectory Unlocked
13:41:55.695 [main] DEBUG org.ehcache.core.internal.service.ServiceLocator - All Services successfully stopped, 17 Services in 0ms
13:41:55.695 [main] DEBUG org.ehcache.core.EhcacheManager - Close successful.

Process finished with exit code 0

2)测试heap和offheap

设置heap个数为1,offheap大小为1MB(offheap最小为1MB)

// 测试heap容纳个数和offheap,将配置中其它无关配置注释掉
// 设置缓存堆容纳元素个数(JVM内存空间)
.heap(1L, EntryUnit.ENTRIES)
// 设置堆外储存大小(内存存储)
.offheap(1L, MemoryUnit.MB)
// 配置磁盘持久化储存(硬盘存储)
//.disk(500L, MemoryUnit.MB, false)
public static void main(String[] args) throws InterruptedException, FileNotFoundException {
    // 初始化Ehcache对象
    new EhcacheUtil();
    // 获取初始化的缓存对象
    Cache<String, String> mineCache = cacheManager.getCache("defaultCache", String.class, String.class);
    // 创建测试内容
    StringBuilder strTemp = new StringBuilder("测试");
    strTemp.append("测试一二三四五六七八九十");
    System.out.println("大小为:" + strTemp.toString().getBytes() + "Byte");
    // 存入第1条数据
    mineCache.put("key", strTemp.toString());
    // 取出并输出
    System.out.println("key:" + mineCache.get("key"));
    strTemp = new StringBuilder("测试2");
    // 存入第2条数据
    mineCache.put("key2", strTemp.toString());
    // 取出并输出
    System.out.println("key2:" + mineCache.get("key2"));
    // 取出并输出第一条数据,由于offheap的个存在所以当存入第2条数据时,第一条会被存储到offheap中而不会被淘汰
    System.out.println("key:" + mineCache.get("key"));
    // 关闭ehcache
    cacheManager.close();
}
由于控制台日志太多下面只截取部分有用日志
[Ehcache配置初始化<开始>]
[Ehcache配置初始化<完成>]
key:测试测试一二三四五六七八九十
key2:测试2
key:测试测试一二三四五六七八九十
14:01:41.686 [main] DEBUG org.ehcache.core.EhcacheManager - Close successful.
Process finished with exit code 0

设置第一条记录的大小大于offheap 的大小

public static void main(String[] args) throws InterruptedException, FileNotFoundException {
    // 初始化Ehcache对象
    new EhcacheUtil();
    // 获取初始化的缓存对象
    Cache<String, String> mineCache = cacheManager.getCache("defaultCache", String.class, String.class);
    // 创建测试内容
    StringBuilder strTemp = new StringBuilder("测试");
    while(strTemp.toString().getBytes().length <= 1024*1024){
        strTemp.append("测试一二三四五六七八九十");
    }
    System.out.println("大小为:" + strTemp.toString().getBytes().length + " Byte,1MB大小为:" + 1024*1024 + " Byte");
    // 存入第1条数据
    mineCache.put("key", strTemp.toString());
    // 取出并输出
    System.out.println("key:" + mineCache.get("key"));
    strTemp = new StringBuilder("测试2");
    // 存入第2条数据
    mineCache.put("key2", strTemp.toString());
    // 取出并输出
    System.out.println("key2:" + mineCache.get("key2"));
    // 取出并输出第一条数据,由于offheap的个存在所以当存入第2条数据时,第一条会被存储到offheap中,但是第一条数据的大小大于offheap所以会被淘汰
    System.out.println("key:" + mineCache.get("key"));
    // 关闭ehcache
    cacheManager.close();
}
[Ehcache配置初始化<开始>]
[Ehcache配置初始化<完成>]
大小为:1048578 Byte,1MB大小为:1048576 Byte
14:06:50.926 [main] DEBUG org.terracotta.offheapstore.paging.OffHeapStorageArea - Data area expanded from 1020.0KB to 1022.0KB [occupation=0.0]
14:06:50.926 [main] DEBUG org.terracotta.offheapstore.paging.UpfrontAllocatingPageSource - Allocating a 2KB buffer from chunk 0 &2048
14:06:50.926 [main] DEBUG org.terracotta.offheapstore.paging.OffHeapStorageArea - Data area expanded from 1022.0KB to 1MB [occupation=0.0]
14:06:50.967 [main] DEBUG org.terracotta.offheapstore.paging.OffHeapStorageArea - Data area expansion from 1046528 failed
14:06:50.977 [main] INFO org.ehcache.core.internal.resilience.LoggingRobustResilienceStrategy - Ehcache key key recovered from
org.ehcache.core.spi.store.StoreAccessException: The element with key 'key' is too large to be stored in this offheap store.
	at org.ehcache.impl.internal.store.offheap.AbstractOffHeapStore.computeWithRetry(AbstractOffHeapStore.java:1101)
	at org.ehcache.impl.internal.store.offheap.AbstractOffHeapStore.put(AbstractOffHeapStore.java:316)
	at org.ehcache.impl.internal.store.tiering.TieredStore.put(TieredStore.java:138)
	at org.ehcache.core.Ehcache.put(Ehcache.java:198)
	at com.linewell.egov.config.EhcacheUtil.main(EhcacheUtil.java:157)
Caused by: org.terracotta.offheapstore.exceptions.OversizeMappingException: Storage Engine and Eviction Failed - Empty Map
Storage Engine : OffHeapBufferStorageEngine allocated=1022.0KB occupied=0B
Storage Area: OffHeapStorageArea
	511 2KB pages
Allocator: org.terracotta.offheapstore.storage.allocator.IntegerBestFitAllocator@229c6181
Page Source: UpfrontAllocatingPageSource
Chunk 1
Size             : 1MB
Free Allocator   : PowerOfTwoAllocator: Occupied 1022.5KB [Largest Available Area 1KB]
Victim Allocator : PowerOfTwoAllocator: Occupied 512B [Largest Available Area 512KB]
	at org.terracotta.offheapstore.AbstractOffHeapClockCache.storageEngineFailure(AbstractOffHeapClockCache.java:84)
	at org.terracotta.offheapstore.OffHeapHashMap.writeEntry(OffHeapHashMap.java:689)
	at org.terracotta.offheapstore.OffHeapHashMap.computeWithMetadata(OffHeapHashMap.java:1947)
	at org.terracotta.offheapstore.AbstractLockedOffHeapHashMap.computeWithMetadata(AbstractLockedOffHeapHashMap.java:582)
	at org.terracotta.offheapstore.concurrent.AbstractConcurrentOffHeapMap.computeWithMetadata(AbstractConcurrentOffHeapMap.java:743)
	at org.ehcache.impl.internal.store.offheap.EhcacheConcurrentOffHeapClockCache.compute(EhcacheConcurrentOffHeapClockCache.java:152)
	at org.ehcache.impl.internal.store.offheap.AbstractOffHeapStore.computeWithRetry(AbstractOffHeapStore.java:1099)
	... 4 common frames omitted
key:null
14:06:54.070 [main] DEBUG org.terracotta.offheapstore.paging.UpfrontAllocatingPageSource - Freeing a 2KB buffer from chunk 0 &2048
14:06:54.070 [main] DEBUG org.terracotta.offheapstore.paging.UpfrontAllocatingPageSource - Allocating a 2KB buffer from chunk 0 &1046528
14:06:54.070 [main] DEBUG org.terracotta.offheapstore.paging.OffHeapStorageArea - Data area expanded from 2KB to 4KB [occupation=0.0]
key2:测试2
key:null
Disconnected from the target VM, address: '127.0.0.1:63287', transport: 'socket'
14:06:56.191 [main] DEBUG org.ehcache.core.internal.service.ServiceLocator - All Services successfully stopped, 17 Services in 10ms
14:06:56.191 [main] DEBUG org.ehcache.core.EhcacheManager - Close successful.
Process finished with exit code 0

关于TTL和TTI的测试这里就不贴代码了得出结论是TTL和TTI同时配置时,二者不可共存后面的配置会覆盖前面的,XML配置同理

二、xml版本配置

在resource文件夹下创建ehcache.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">
    <!-- 持久化路径 -->
    <persistence directory="D:/ehcacheData"/>

    <!-- 缓存模版,此处为了显示其用法,也可以不用模版直接在cache中配置与模版参数相同 -->
    <cache-template name="template">
        <key-type>java.lang.String</key-type>
        <value-type>java.lang.String</value-type>
        <expiry>
            <!-- 单位默认为秒当用秒作单位时,可以不填-->
            <ttl unit="hours">1</ttl>
        </expiry>
        <resources>
            <!-- 单位默认为entries当用entries作单位时,可以不填-->
            <heap>1</heap>
            <offheap unit="MB">1</offheap>
            <!-- persistent 默认为false可以不填-->
            <disk unit="MB">20</disk>
        </resources>
    </cache-template>

    <!-- 缓存对象,如果使用了模版会覆盖模版中的内容,使用uses-template=""来引用模版 -->
    <cache alias="defaultCache" uses-template="template">
        <expiry>
            <!--此处会覆盖模版中的(TTL)配置 -->
            <tti>60</tti>
        </expiry>
        <resources>
            <disk unit="MB" persistent="true"> 500</disk>
        </resources>
        <!-- 没有研究这块,暂时先不管
        <eviction-advisor></eviction-advisor>
        -->
    </cache>
</config>
   public EhcacheUtil() {
        System.out.println("[Ehcache配置初始化<开始>]");
        // 配置默认缓存属性
        cacheManager = CacheManagerBuilder.newCacheManager(new XmlConfiguration(getClass().getResource("/ehcache.xml")));
        cacheManager.init();
        System.out.println("[Ehcache配置初始化<完成>]");
    }

应该也可以这样配置到application.yml中,可自行尝试

spring:
  cache:
    ehcache:
      config: ehcache.xml
// ehcache3.5.2中缓存过期策略有所更新旧的方法参数已经过期新参数设置可以参考下面
// 过期策略设置为不过期
.withExpiry(ExpiryPolicy.NO_EXPIRY)

如需转载求标明出处, https://blog.csdn.net/Gentlemike/article/details/80403967

评论 3 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页

打赏作者

向南向北

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值