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 唯一,最好是类名+方法名+业务键 -->
<!-- 设定缓存的默认数据过期策略 -->
<defaultCache
maxElementsInMemory="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
@Configuration
public 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: ehcache
ehcache:
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;
@Service
public 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 是什么。