springboot中ehcache的使用
為什麼要在系統中使用快取,很簡單,為了提高資料的獲取效率,快取一些經常用到的基礎資料,避免重複查詢資料庫,完全沒有那個必須要,但是使用了快取又帶來了問題,快取失效,快取穿透,快取更新的問題,這些都是需要具體的業務場景逐一的去解決.今天先說怎麼使用ehcache.
- 新增依賴:
<!-- 快取 --><dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId
現在ehcache已經到了版本3.5了,這樣引入的依賴還是2.X版本的,這次不做詳細的研究.暫時先用2.x版本
- 在springboot的啟動類上添加註解
@EnableCaching
- 配置檔案
import net.sf.ehcache.config.CacheConfiguration; import org.springframework.cache.CacheManager; import org.springframework.cache.annotation.CachingConfigurer; import org.springframework.cache.annotation.EnableCaching; import org.springframework.cache.ehcache.EhCacheCacheManager; import org.springframework.cache.interceptor.CacheErrorHandler; import org.springframework.cache.interceptor.CacheResolver; import org.springframework.cache.interceptor.KeyGenerator; import org.springframework.cache.interceptor.SimpleKeyGenerator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * EhCache配置檔案,可以替代ehcache.xml 檔案 */ @Configuration public class EhCacheConfiguration implements CachingConfigurer { @Bean(destroyMethod="shutdown") public net.sf.ehcache.CacheManager ehCacheManager() { CacheConfiguration cacheConfiguration = new CacheConfiguration(); cacheConfiguration.setName("taskLog"); cacheConfiguration.setMemoryStoreEvictionPolicy("LRU"); cacheConfiguration.setMaxEntriesLocalHeap(1000); net.sf.ehcache.config.Configuration config = new net.sf.ehcache.config.Configuration(); //可以建立多個cacheConfiguration,都新增到Config中 config.addCache(cacheConfiguration); return net.sf.ehcache.CacheManager.newInstance(config); } @Bean @Override public CacheManager cacheManager() { return new EhCacheCacheManager(ehCacheManager()); } @Bean @Override public KeyGenerator keyGenerator() { return new SimpleKeyGenerator(); } @Override public CacheResolver cacheResolver() { return null; } @Override public CacheErrorHandler errorHandler() { return null; } }
配置檔案的方式二:
建立ehcache.xml,同時配置: spring.cache.ehcache.config= classpath:ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd">
<!--timeToIdleSeconds 當快取閒置n秒後銷燬 -->
<!--timeToLiveSeconds 當快取存活n秒後銷燬 -->
<!-- 快取配置
name:快取名稱。
maxElementsInMemory:快取最大個數。
eternal:物件是否永久有效,一但設定了,timeout將不起作用。
timeToIdleSeconds:設定物件在失效前的允許閒置時間(單位:秒)。僅當eternal=false物件不是永久有效時使用,可選屬性,預設值是0,也就是可閒置時間無窮大。
timeToLiveSeconds:設定物件在失效前允許存活時間(單位:秒)。最大時間介於建立時間和失效時間之間。僅當eternal=false物件不是永久有效時使用,預設是0.,也就是物件存活時間無窮大。
overflowToDisk:當記憶體中物件數量達到maxElementsInMemory時,Ehcache將會物件寫到磁碟中。 diskSpoolBufferSizeMB:這個引數設定DiskStore(磁碟快取)的快取區大小。預設是30MB。每個Cache都應該有自己的一個緩衝區。
maxElementsOnDisk:硬碟最大快取個數。
diskPersistent:是否快取虛擬機器重啟期資料 Whether the disk
store persists between restarts of the Virtual Machine. The default value
is false.
diskExpiryThreadIntervalSeconds:磁碟失效執行緒執行時間間隔,預設是120秒。 memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理記憶體。預設策略是
LRU(最近最少使用)。你可以設定為FIFO(先進先出)或是LFU(較少使用)。
clearOnFlush:記憶體數量最大時是否清除。 -->
<!-- 磁碟快取位置 -->
<diskStore path="java.io.tmpdir" />
<!-- 預設快取 -->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxElementsOnDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap" />
</defaultCache>
<!-- 測試 -->
<cache name="nurse"
eternal="false"
timeToIdleSeconds="2400"
timeToLiveSeconds="2400"
maxEntriesLocalHeap="10000"
maxEntriesLocalDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU">
</cache>
</ehcache>
ehcache.xml配置檔案詳解
- diskStore:為快取路徑,ehcache分為記憶體和磁碟兩級,此屬性定義磁碟的快取位置。
- defaultCache:預設快取策略,當ehcache找不到定義的快取時,則使用這個快取策略。只能定義一個。
- name:快取名稱。
- maxElementsInMemory:快取最大數目
- maxElementsOnDisk:硬碟最大快取個數。
- eternal:物件是否永久有效,一但設定了,timeout將不起作用。
- overflowToDisk:是否儲存到磁碟,當系統宕機時
- timeToIdleSeconds:設定物件在失效前的允許閒置時間(單位:秒)。僅當eternal=false物件不是永久有效時使用,可選屬性,預設值是0,也就是可閒置時間無窮大。
- timeToLiveSeconds:設定物件在失效前允許存活時間(單位:秒)。最大時間介於建立時間和失效時間之間。僅當eternal=false物件不是永久有效時使用,預設是0.,也就是物件存活時間無窮大。
- diskPersistent:是否快取虛擬機器重啟期資料 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
- diskSpoolBufferSizeMB:這個引數設定DiskStore(磁碟快取)的快取區大小。預設是30MB。每個Cache都應該有自己的一個緩衝區。
- diskExpiryThreadIntervalSeconds:磁碟失效執行緒執行時間間隔,預設是120秒。
- memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理記憶體。預設策略是LRU(最近最少使用)。你可以設定為FIFO(先進先出)或是LFU(較少使用)。
- clearOnFlush:記憶體數量最大時是否清除。
Cache註解詳解
- @CacheConfig:主要用於配置該類中會用到的一些共用的快取配置。在這裡@CacheConfig(cacheNames = "users"):配置了該資料訪問物件中返回的內容將儲存於名為users的快取物件中,我們也可以不使用該註解,直接通過@Cacheable自己配置快取集的名字來定義。
- @Cacheable:配置了findByName函式的返回值將被加入快取。同時在查詢時,會先從快取中獲取,若不存在才再發起對資料庫的訪問。該註解主要有下面幾個引數:
- value、cacheNames:兩個等同的引數(cacheNames為Spring 4新增,作為value的別名),用於指定快取儲存的集合名。由於Spring 4中新增了@CacheConfig,因此在Spring 3中原本必須有的value屬性,也成為非必需項了
- key:快取物件儲存在Map集合中的key值,非必需,預設按照函式的所有引數組合作為key值,若自己配置需使用SpEL表示式,比如:@Cacheable(key = "#p0"):使用函式第一個引數作為快取的key值,更多關於SpEL表示式的詳細內容可參考官方文件
- condition:快取物件的條件,非必需,也需使用SpEL表示式,只有滿足表示式條件的內容才會被快取,比如:@Cacheable(key = "#p0", condition = "#p0.length() < 3"),表示只有當第一個引數的長度小於3的時候才會被快取,若做此配置上面的AAA使用者就不會被快取,讀者可自行實驗嘗試。
- unless:另外一個快取條件引數,非必需,需使用SpEL表示式。它不同於condition引數的地方在於它的判斷時機,該條件是在函式被呼叫之後才做判斷的,所以它可以通過對result進行判斷。
- keyGenerator:用於指定key生成器,非必需。若需要指定一個自定義的key生成器,我們需要去實現org.springframework.cache.interceptor.KeyGenerator介面,並使用該引數來指定。需要注意的是:該引數與key是互斥的
- cacheManager:用於指定使用哪個快取管理器,非必需。只有當有多個時才需要使用
- cacheResolver:用於指定使用那個快取解析器,非必需。需通過org.springframework.cache.interceptor.CacheResolver介面來實現自己的快取解析器,並用該引數指定。
除了這裡用到的兩個註解之外,還有下面幾個核心註解:
- @CachePut:配置於函式上,能夠根據引數定義條件來進行快取,它與@Cacheable不同的是,它每次都會真是呼叫函式,所以主要用於資料新增和修改操作上。它的引數與@Cacheable類似,具體功能可參考上面對@Cacheable引數的解析
- @CacheEvict:配置於函式上,通常用在刪除方法上,用來從快取中移除相應資料。除了同@Cacheable一樣的引數之外,它還有下面兩個引數:
- allEntries:非必需,預設為false。當為true時,會移除所有資料
- beforeInvocation:非必需,預設為false,會在呼叫方法之後移除資料。當為true時,會在呼叫方法之前移除資料。
具體使用:
@CacheConfig(cacheNames = "users") public interface UserRepository extends JpaRepository<User, Long> { @Cacheable User findByName(String name); }
//這樣會預設進行快取
註解中如果使用字串作為key必須是:
//這裡的單引號不能少,否則會報錯,被識別是一個物件;
public static final String CACHE_KEY = "'toolkeys'";
/**
* value屬性表示使用哪個快取策略,快取策略在ehcache.xml
*/
public static final String TOOL_CACHENAME = "tool";
@CacheEvict(value=TOOL_CACHENAME,key=CACHE_KEY)
public String findById(Long id){
System.err.println("沒有走快取!"+id);
return id.toString();
}
/**
* 在支援Spring Cache的環境下,對於使用@Cacheable標註的方法,Spring在每次執行前都會檢查Cache中是否存在相同key的快取元素,如果存在就不再執行該方法,而是直接從快取中獲取結果進行返回,否則才會執行並將返回結果存入指定的快取中。@CachePut也可以宣告一個方法支援快取功能。與@Cacheable不同的是使用@CachePut標註的方法在執行前不會去檢查快取中是否存在之前執行過的結果,而是每次都會執行該方法,並將執行結果以鍵值對的形式存入指定的快取中。
@CachePut也可以標註在類上和方法上。使用@CachePut時我們可以指定的屬性跟@Cacheable是一樣的。
*/
@CachePut(value = TOOL_CACHENAME,key = "'toolkeys_'+#updated.getId()")
public String update(String name) {
return name;
}
反正使用上就是這麼的簡單,下次我們來說ehcache的實現,以及快取的管理.
2018年9月19日16:53:49