1. 程式人生 > >JAVA中使用springBoot和Ehcache3.X無xml配置和xml配置

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

我用的是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: 
[email protected]
* 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.t
imeToLiveExpiration( //設定快取過期時間 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> : [email protected]
13:41:55.485 [main] DEBUG org.ehcache.impl.internal.spi.serialization.DefaultSerializationProvider - Serializer for <java.lang.String> : [email protected]
13:41:55.495 [main] DEBUG org.ehcache.impl.internal.spi.copy.DefaultCopyProvider - Copier for <java.lang.String> : [email protected]
13:41:55.495 [main] DEBUG org.ehcache.impl.internal.spi.copy.DefaultCopyProvider - Copier for <java.lang.String> : [email protected]
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.te[email protected]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

相關推薦

JAVA使用springBootEhcache3.Xxml配置xml配置

我用的是springBoot和Ehcache3.31.在maven的pom.xml匯入ehcache3.3.0依賴<!-- Ehcache 快取--> <dependency> <groupId>org.ehcache</gr

JavaIO流文件讀取、寫入復制

復制 循環 int files catch class close brush system //構造文件File類 File f=new File(fileName); //判斷是否為目錄 f.isDirectory(); //獲取目錄下的文件名 String[] fil

JAVA日期 yyyy-MM-dd HH:mm:ssyyyy-MM-dd hh:mm:ss的區別

pac color test orm nbsp spa div rbegin println JAVA中日期 yyyy-MM-dd HH:mm:ss和yyyy-MM-dd hh:mm:ss的區別 : HH:24小時制 hh:12小時制 package t

JAVA返回類型使用泛型TObject有什麽區別?

some http cast one gpo aud pre 使用 安全 最近在讀jackson源碼的時候發現有段代碼返回類型寫的是<T> T,而我自己一般寫的是Object。上網搜了下這個語法糖,在stackoverflow上找到一個比較簡單易懂的解釋,搬運過

java為什麽接口中的屬性方法都默認為public?

默認 bsp hole chapter -s 勝任 做出 com public 4)為什麽接口中的屬性和方法都默認為public?Sun公司當初為什麽要把java的接口設計發明成這樣? 【新手可忽略不影響繼續學習】(視頻下載) (全部書籍)答:如上所述,馬克-to-win:

java介面(interface)及使用方法注意事項

1、介面:一種把類抽象的更徹底,接口裡只能包含抽象方法的“特殊類”。介面不關心類的內部狀態資料,定義的是一批類所遵守的規範。(它只規定這批類裡必須提供某些方法,提供這些方法就可以滿足實際要求)。 在JAVA程式語言中是一個抽象型別,是抽象方法的集合,介面通常以interface來宣告。一個類通過

java的移位運算子與符號位移

引用: java中有三種移位運算子 java中有三種移位運算子 << : 左移運算子,num << 1,相當於num乘以2 >> : 右移運算子,num >> 1,相當於num除以2,對於奇數,右邊

Java使用FastJSON進行物件的序列化反序列化

Java中使用FastJSON進行物件的序列化和反序列化 1.新增依賴,maven的pom.xml檔案中新增以下依賴 <dependency> <groupId>com.alibaba</groupId> <arti

javaHashMap、CurrentHashMap 工作原理&&HashTable、HashSet的區別

HashMap和HashTable的區別 HashMap儲存的是鍵值對(接受null鍵值對),不支援synchronized,速度很快; HashTable不接受null鍵值對,可同步(Synchronized) 雖然HashMap是非Synchronized,但collection

java構造程式碼塊、static程式碼塊區域性程式碼塊的區別

先上程式碼: class StaticCode{ int age; // static程式碼塊 static{ System.out.println("static程式碼塊"); } //構造程式碼塊

JavaBIO、NIO、AIO的區別應用場景

    學習IO,首先要明白四個東西。 1.同步         java自己去處理io。 2.非同步 java將io交給作業系統去處理,告訴快取區大小,處理完成回撥。 3.阻塞  使用阻塞IO時,Java呼叫會一直阻塞到讀寫完成才返回。 4.非阻塞 使用非阻塞IO時,如果不能立馬讀寫,Java呼叫會馬上返

Java的執行緒Thread方法之---suspend()resume()

案例一:(通過打斷點除錯) package com.threadstop.demo; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.u

Java 的異常處理機制的簡單原理應用

異常是指 java 程式執行時(非編譯)所發生的非正常情況或錯誤,與現實生活中的事件很 相似,現實生活中的事件可以包含事件發生的時間、地點、人物、情節等資訊,可以用一個 物件來表示,Java 使用面向物件的方式來處理異常,它把程式中發生的每個異常也都分別封 裝到一個物件來表示

JavaArrays.sort()自定義陣列的升序降序排序

Java學習中會遇到對陣列進行升序或者降序排序的問題 Java語言提供給我們Array.sort(int [] arr)對陣列進行升序排列 import java.util.Arrays; public class Test1 { public stat

JAVAAction層, Service層 ,modle層 Dao層的功能區分

首先這是現在最基本的分層方式,結合了SSH架構。modle層就是對應的資料庫表的實體類。Dao層是使用了hibernate連線資料庫、操作資料庫(增刪改查)。Service層:引用對應的Dao資料庫操作,在這裡可以編寫自己需要的程式碼(比如簡單的判斷)。Action層:引用

java多型父類的成員變數方法呼叫問題

class Super { String name = "父類名字"; public void setName(String name) { System.out.println(this.getClass());

java 標準輸出與標準錯誤 out與 err 區別 用法 聯絡 java的out與err區別 System.outSystem.err的區別 System.out.printlnSystem.err.println的區別 Java重定向S

/** * The "standard" output stream. This stream is already * open and ready to accept output data. Typically this stream * corresponds

Java的迴圈,對比while/do-whilefor(;;)/foreach

 一.while迴圈 while(條件表示式){迴圈體} 當條件滿足時執行迴圈體。 二.do-while do{迴圈體}while(條件表示式); 與while迴圈不同的是,do-while即使不滿足條件表示式也會執行1次迴圈體。 三.for(初始;條件;迴圈)

Javafinal、finally、finalize的區別用法

1.簡單區別 final用於宣告屬性,方法和類,分別表示屬性不可交變,方法不可覆蓋,類不可繼承。 finally是異常處理語句結構的一部分,表示總是執行。 finalize是Object類的一個方法,在垃圾收集器執行的時候會呼叫被回收物件的此方法,供垃圾收集時的其他資源回收,例

淺談java的淺拷貝(淺複製)深拷貝(深複製)

淺拷貝: 淺拷貝又稱為淺複製,淺克隆,淺拷貝是指拷貝時只拷貝物件本身(包括物件中的基本變數),而不拷貝物件包含的引用所指向的物件,拷貝出來的物件的所有變數的值都含有與原來物件相同的值,而所有對其他物件的引用都指向原來的物件,簡單地說,淺拷貝只拷貝物件不拷貝引用