Ehcache 2.x 使用
添加依赖
// ~ cache==========================// ehcache3 更规范,要求有序列化,相对来说比较难用implementation 'org.springframework.boot:spring-boot-starter-cache:2.4.13'implementation 'net.sf.ehcache:ehcache'
编写 ehcache.xml 文件
<?xml version="1.0" encoding="UTF-8"?><ehcache><!-- 当你缓存大量数据的时候,请自行创建自己的缓存配置--><!-- 指定一个文件目录,当 EhCache把数据写到硬盘上时,将把数据写到这个文件目录下 --><diskStore path="java.io.tmpdir/ehcache"/><!--缓存配置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:内存数量最大时是否清除。--><!--注意:由于是公共的缓存管理器,在使用 @Cacheable 的时候请让自己的 key 唯一,最好是类名+方法名+业务键 --><!-- 设定缓存的默认数据过期策略 --><defaultCachemaxElementsInMemory="10000"eternal="false"overflowToDisk="true"timeToIdleSeconds="10"timeToLiveSeconds="20"diskPersistent="false"diskExpiryThreadIntervalSeconds="120"/><!-- 由于本项目的场景基本上都是缓存大量全局数据,闲置和过期时间都可以变得较大 --><cache name="common:cache:2m"maxElementsInMemory="100000"eternal="false"overflowToDisk="false"timeToIdleSeconds="90"timeToLiveSeconds="180"/><cache name="common:cache:5m"maxElementsInMemory="100000"eternal="false"overflowToDisk="false"timeToIdleSeconds="150"timeToLiveSeconds="300"/><cache name="common:cache:10m"maxElementsInMemory="100000"eternal="false"overflowToDisk="false"timeToIdleSeconds="300"timeToLiveSeconds="600"/><cache name="common:cache:20m"maxElementsInMemory="100000"eternal="false"overflowToDisk="false"timeToIdleSeconds="600"timeToLiveSeconds="1200"/><cache name="common:cache:30m"maxElementsInMemory="100000"eternal="false"overflowToDisk="false"timeToIdleSeconds="900"timeToLiveSeconds="1800"/><cache name="common:cache:1h"maxElementsInMemory="100000"eternal="false"overflowToDisk="false"timeToIdleSeconds="1800"timeToLiveSeconds="3600"/><cache name="common:cache:2h"maxElementsInMemory="100000"eternal="false"overflowToDisk="false"timeToIdleSeconds="3600"timeToLiveSeconds="7200"/><!-- 后面的的为单独的业务模块声明的 cache 配置 --><!-- token 发放缓存 --><cache name="accessTokenGrant:cache:30m"maxElementsInMemory="1000000"eternal="false"overflowToDisk="false"timeToIdleSeconds="900"timeToLiveSeconds="1800"/><!-- 用户信息缓存 发放缓存 --><cache name="userinfo:cache:5m"maxElementsInMemory="100000"eternal="false"overflowToDisk="false"timeToIdleSeconds="150"timeToLiveSeconds="300"/></ehcache>
编写自动配置类,其实最组主要的是声明 @EnableCaching注解,关于 EhCacheNames 这是声明公用的 cache name
package cn.mrcode.autoconfig;import org.springframework.cache.annotation.EnableCaching;import org.springframework.context.annotation.Configuration;/*** <pre>* 全局公共缓存配置,这里只是针对一些公共的配置进行了 type 类型的配置;** 如果你有大量数据进行缓存时,请创建自己的缓存* </pre>** @author mrcode*/@EnableCaching@Configurationpublic class CacheManagerConfig {/*** <pre>* 这里的缓存都是最大存活时间,闲置时间是存活时间的一半* 闲置不使用则自动被驱逐* </pre>*/public interface EhCacheNames {/*** 2 分钟缓存组*/String CACHE_COMMON_2MINS = "common:cache:2m";/*** 5 分钟缓存组*/String CACHE_COMMON_5MINS = "common:cache:5m";/*** 10 分钟缓存组*/String CACHE_COMMON_10MINS = "common:cache:10m";/*** 20 分钟缓存组*/String CACHE_COMMON_20MINS = "common:cache:20m";/*** 30 分钟缓存组*/String CACHE_COMMON_30MINS = "common:cache:30m";/*** 1 小时缓存组*/String CACHE_COMMON_1HOUR = "common:cache:1h";/*** 2 小时缓存组*/String CACHE_COMMON_2HOUR = "common:cache:2h";}}
applicathion.yml 指定 cache 类型和配置文件
spring:cache:type: ehcacheehcache:config: classpath:/ehcache.xml
然后就可以开始使用了
import org.springframework.cache.annotation.CachePut;import org.springframework.cache.annotation.Cacheable;import org.springframework.stereotype.Service;import cn.mrcode.cachepdp.eshop.cache.model.ProductInfo;import cn.mrcode.cachepdp.eshop.cache.service.CacheService;@Servicepublic class CacheServiceImpl implements CacheService {public static final String CACHE_NAME = "local";/*** 将商品信息保存到本地缓存中*/@CachePut(value = CACHE_NAME, key = "'key_'+#productInfo.getId()")public ProductInfo saveLocalCache(ProductInfo productInfo) {return productInfo;}/*** 从本地缓存中获取商品信息*/@Cacheable(value = CACHE_NAME, key = "'key_'+#id")public ProductInfo getLocalCache(Long id) {return null;}}m
对于这个 key 的定义来说,还可以使用 SpEL 表达式,比如下面这个
@Cacheable(cacheNames = CACHE_COMMON_2MINS, key = "#root.targetClass + '_'+ #root.method + '_' + #brand")public MlsBrands getByNameForCache(String brand) {return getByName(brand);}
root.targetClass:表示获取当前类路径类名root.method:当前方法名称,在这里是 getByNameForCache- 后面没有加 root 的表示从参数中获取,这里就是 brand 这个字符串的入参的值,比如传递 a,那么就是 a
key:表示存储的时候,缓存的 key 是什么。
