一、EhCache简介
Spring 从 3.1 开始引入对 Cache 的支持,并支持使用JCache(JSR-107)注解简化开发。Cache 接口下 Spring 提供了各种 xxxCache 的实现,其中就包括了EhCache。
EhCache 是一个纯 Java 的进程内缓存框架,是 Hibernate 中默认的 CacheProvider,同Redis一样,EhCache 不是纯内存缓存,它支持基于内存和磁盘的二级缓存,本文所使用的EhCache3还增加了堆外缓存的支持,同时 EhCache 还原生支持集群能力。
本文只介绍 EhCache 的使用,就不过多赘述理论了,EhCache 功能十分强大,且简单易上手,一小时不到即可集成到项目中。
二、集成方法
1. 引入依赖
说明:JCache是Java规范中定义的一套缓存API,我们这里需要使用JCache中提供的API,所以要加上JCache的依赖。
<!-- EhCache相关组件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.cache/cache-api -->
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.ehcache/ehcache -->
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.10.8</version>
</dependency>
<!-- EhCache相关组件 -->
2. 添加配置文件
2.1 配置application.yml
指定缓存类型及配置文件位置。
spring:
cache:
type: jcache
jcache:
config: classpath:ehcache.xml
2.2 配置XML文件
将XML文件放在与application.yml同级的resource目录下即可;配置完成后启动服务,如果无报错说明操作正确。
关于XML文件如何配置:常用的基本功能如下代码段,如有扩展需求的请前往官网查找。
<config xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns = "http://www.ehcache.org/v3"
xsi:schemaLocation = "http://www.ehcache.org/v3 http://www.ehcache.org/schema/ehcache-core-3.0.xsd">
<!-- 缓存持久化配置: 定义磁盘缓存位置 -->
<!--<persistence directory="D:/cache"/>-->
<!-- 缓存模板: 未填写缓存名时使用的默认缓存,同时也可被继承 -->
<cache-template name="defaultCache">
<expiry>
<ttl>5</ttl>
</expiry>
<resources>
<heap>100</heap>
<offheap unit="MB">50</offheap>
</resources>
</cache-template>
<!-- 缓存列表: 自定义缓存配置 -->
<cache alias="CacheConfig1" uses-template="defaultCache">
<expiry>
<ttl unit="seconds">10</ttl>
</expiry>
</cache>
<cache alias="CacheConfig2" uses-template="defaultCache">
<expiry>
<ttl unit="minutes">5</ttl>
</expiry>
</cache>
<cache alias="CacheConfig3" uses-template="defaultCache">
<expiry>
<ttl unit="hours">1</ttl>
</expiry>
</cache>
</config>
三、实际应用
1. 功能介绍
表内存储一定量的数据,一段时间内用户调用分页查询接口,当查询条件不变时,返回缓存中数据而不是重新查询数据库;以下是一个简单的demo。
2. 具体实现
2.1 Controller层
传入视频名称及分页条件,返回所有相同名称的视频分页。
@Autowired
private VideoService videoService;
@RequestMapping(value = "/selectChildVideo", method = RequestMethod.GET)
public IPage<Video> selectChildVideo(
@RequestParam(value = "name") String name,
Integer pageNum, Integer pageSize) {
return videoService.selectChildVideo(name, pageNum, pageSize);
}
2.2 ServiceImpl层
使用@Cachable注解提示该方法使用缓存,缓存配置使用"CacheConfig3",缓存键为"'ChildVideo' + #name + #pageNum + #pageSize"(此处为SpEL表达式,值为传入参数的实际值);
@Autowired
private VideoMapper videoMapper;
@Override
@Cacheable(value = "CacheConfig3",
key = "'ChildVideo' + #name + #pageNum + #pageSize")
public IPage<Video> selectChildVideo(String name, Integer pageNum, Integer pageSize) {
return videoMapper.selectPage(
new Page<>(pageNum, pageSize),
new LambdaQueryWrapper<Video>().like(StrUtil.isNotEmpty(name), Video::getName, name));
}
value | 指定使用的缓存配置; |
key | 指定缓存的键,当命中缓存中同名键后程序便不会进入方法体中; |
keyGenerator | key生成器,与key属性互斥,选用其一即可; |
cacheManager | 指定缓存管理器; |
condition | 指定缓存条件,优先级大于unless,只有满足条件才缓存; |
unless | 当unless指定的条件为false才缓存; |
sync | 是否异步缓存。 |
引用:
一文详细介绍Ehcache - 知乎 (zhihu.com)
JAVA中使用最广泛的本地缓存?Ehcache的自信从何而来 —— 感受来自Ehcache的强大实力 - 知乎 (zhihu.com)