springboot配置ehcache2.X緩存(@Cacheable等注解和手動操作緩存的工具類 支持element粒度的時間設置)


本文只寫出一些注意事項和源碼,請善用官方文檔~

注解實現

@Cacheable @CachePut @CacheEvit
啟動類上加@EnableCaching就可以開啟緩存
由文檔可知,自動檢測緩存實現的默認順序為
1.Generic
2.JCache (JSR-107) (EhCache 3, Hazelcast, Infinispan, and others)
3.EhCache 2.x
4.Hazelcast
5.Infinispan
6.Couchbase
7.Redis
8.Caffeine
9.Simple
默認是1,ConcurrentHashMap的實現
在classpath下放入ehcache.xml並在pom.xml中添加依賴就可以切換到EhCache 2.x
注意:net.sf.ehcache是2.X org.ehcache是3.X
spring.cache.cache-names不生效,需要在ehcache.xml中配置,注解使用了不存在的cacheName會報錯
注解中key的值可以由el表達式拼接,例如

@Cacheable(value = "test", key = "#root.targetClass.name +'.'+#root.method.name+':'+#root.args[0]")

https://docs.spring.io/spring/docs/5.1.10.RELEASE/spring-framework-reference/integration.html#cache-spel-context

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
         updateCheck="false">
    <defaultCache maxElementsInMemory="1000"
                  overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="3600"
                  timeToLiveSeconds="3600" memoryStoreEvictionPolicy="LRU"/>
    <!--
       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:內存數量最大時是否清除。
       -->
    <cache name="5s" maxElementsInMemory="100"
           overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="5" timeToLiveSeconds="5"
           memoryStoreEvictionPolicy="LRU"/>
</ehcache>

工具類CacheUtils

先看部分源碼
springboot的CacheManager高層實現(各種緩存框架抽象出來的interface)
EhCacheCacheManager為ehcache的實現對象(仍是spring包下)
getCacheManager()可拿到EhCache低層實現的實例對象(ehcache包下)

Cache也是類似

import net.sf.ehcache.Cache;
import net.sf.ehcache.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.ehcache.EhCacheCacheManager;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CacheUtils {
    private static CacheManager manager;

    @Autowired
    public void setManager(CacheManager manager) {
        CacheUtils.manager = manager;
    }

    public static Object get(String cacheName, Object key) {
        return cache(cacheName).get(key).getObjectValue();
    }

    public static void put(String cacheName, Object key, Object value, Integer ttl, Integer tti) {
        Element e = new Element(key, value);
        //不設置則使用xml配置
        if (ttl != null)
            e.setTimeToLive(ttl);
        if (tti != null)
            e.setTimeToIdle(tti);
        cache(cacheName).put(e);
    }

    public static boolean remove(String cacheName, Object key) {
        return cache(cacheName).remove(key);
    }

    public static void removeAll(String cacheName) {
        cache(cacheName).removeAll();
    }

    private static Cache cache(String cacheName) {
        net.sf.ehcache.CacheManager cacheManager = ((EhCacheCacheManager) manager).getCacheManager();
        if (!cacheManager.cacheExists(cacheName))
            cacheManager.addCache(cacheName);
        return cacheManager.getCache(cacheName);
    }
}
先判斷是否存在對應cacheName的cache,避免空指針異常 timeToIdleSeconds和timeToLiveSeconds,有element級設置以其為准,沒有以ehcache.xml為准


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM