1. 程式人生 > >springboot中ehcache的使用

springboot中ehcache的使用

為什麼要在系統中使用快取,很簡單,為了提高資料的獲取效率,快取一些經常用到的基礎資料,避免重複查詢資料庫,完全沒有那個必須要,​​​​​​但是使用了快取又帶來了問題,快取失效,快取穿透,快取更新的問題,這些都是需要具體的業務場景逐一的去解決.今天先說怎麼使用ehcache.

  1. 新增依賴:

<!-- 快取 --><dependency>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-cache</artifactId

> </dependency><!-- ehcache --><dependency>     <groupId>net.sf.ehcache</groupId>     <artifactId>ehcache</artifactId> </dependency>

現在ehcache已經到了版本3.5,這樣引入的依賴還是2.X版本的,這次不做詳細的研究.暫時先用2.x版本

  1. 在springboot的啟動類上添加註解
@EnableCaching
  1. 配置檔案
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函式的返回值將被加入快取。同時在查詢時,會先從快取中獲取,若不存在才再發起對資料庫的訪問。該註解主要有下面幾個引數:
    • valuecacheNames:兩個等同的引數(cacheNamesSpring 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